【问题标题】:How to implement a custom dynamic interceptor?如何实现自定义动态拦截器?
【发布时间】:2018-01-05 21:23:09
【问题描述】:

我试图想办法利用动态类型来提供其成员的自然使用,但它最终源自Dictionary<string, string> 对象。但是,我希望能够定义如何解析给定属性的规则。这可能吗?

我想要这样的东西。

var dynamicCollection = new MyDyanmicType();
dynamicCollection.Build(/*some dictionary*/); // or just implement an implicit operator
dynamicCollection.MemberProperty; // <-- this should let me search the dictionary how I want for some form of the string "MemberProperty"
dynamicCollection.PropertyThatDoesntExist; // <-- this should give me an opportunity to exhaust my resolution and throw back a custom exception that I choose

用例是我有一些由产品管理人员在数据库中动态设置的字段。不幸的是,我需要防止人为错误的波动。鉴于上述情况,有人可能会输入 memberProperty、Member Property 等,因此我需要控制如何查找声明的成员,同时保持对普通 POCO 的干净使用。

我面临的问题是我有大量的样板字典代码我试图摆脱,这将使我摆脱一些相当讨厌和冗长的运行时检查。

【问题讨论】:

    标签: c# .net expandoobject


    【解决方案1】:

    这比我想象的要容易得多。解决方案看起来是这样的。

    public class AddOnBag : DynamicObject
    {
        private Dictionary<string, string> _addOns;
    
        public static AddOnBag BuildBag(Dictionary<string, string> dict)
        {
            var bag = new AddOnBag {_addOns = dict};
    
            return bag;
        }
    
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            var addOn = LookupAddOn(binder.Name);
    
            result = addOn.Value;
    
            return addOn.Key != null;
        }
    
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            var addOn = LookupAddOn(binder.Name);
    
            if (addOn.Key == null)
            {
                return false;
            }
    
            _addOns[addOn.Key] = value.ToString();
    
            return true;
        }
    
        private KeyValuePair<string, string> LookupAddOn(string name)
        {
            var addOn = _addOns.FirstOrDefault(pair =>
            {
                var stripped = pair.Key.Replace(" ", string.Empty);
                var attempted = name;
    
                return string.Equals(stripped, attempted, StringComparison.OrdinalIgnoreCase);
            });
    
            return addOn;
        }
    }
    

    此外,事实证明,Microsoft 提供了一个非常接近此的示例。

    https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/walkthrough-creating-and-using-dynamic-objects

    使用只需要dynamic 关键字。此外,如果您将方法添加到您创建的类,CLR 足够智能,可以将调用路由到预期的方法,而不是 TryGetMemberTryInvokeMember

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-27
      • 2020-10-11
      • 1970-01-01
      • 1970-01-01
      • 2018-09-15
      • 2018-05-25
      • 1970-01-01
      相关资源
      最近更新 更多