如何实现自定义动态拦截器?
How to implement a custom dynamic interceptor?
我正在想办法利用动态类型来提供其成员的自然使用,但它最终源自 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
用例是我有一些字段由产品管理人员在数据库中动态设置。不幸的是,我需要防范人为错误的波动。鉴于上述情况,有人可能会输入 member属性、Member 属性 等,因此我需要控制如何查找声明的成员,同时保持正常 POCO 的干净使用。
我面临的问题是我有一大堆样板字典代码,我正试图摆脱它,这将使我摆脱一些相当讨厌和冗长的运行时检查。
这比我想象的要容易得多。解决方案看起来像这样。
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 提供了一个非常接近于此的示例。
用法只需要 dynamic
关键字。另外,如果您将方法添加到您创建的 class,CLR 足够智能,可以将调用路由到预期的方法,而不是 TryGetMember
或 TryInvokeMember
.
我正在想办法利用动态类型来提供其成员的自然使用,但它最终源自 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
用例是我有一些字段由产品管理人员在数据库中动态设置。不幸的是,我需要防范人为错误的波动。鉴于上述情况,有人可能会输入 member属性、Member 属性 等,因此我需要控制如何查找声明的成员,同时保持正常 POCO 的干净使用。
我面临的问题是我有一大堆样板字典代码,我正试图摆脱它,这将使我摆脱一些相当讨厌和冗长的运行时检查。
这比我想象的要容易得多。解决方案看起来像这样。
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 提供了一个非常接近于此的示例。
用法只需要 dynamic
关键字。另外,如果您将方法添加到您创建的 class,CLR 足够智能,可以将调用路由到预期的方法,而不是 TryGetMember
或 TryInvokeMember
.