首页> C#>如何只使用Castle.DynamicProxy拦截基类方法
作者:互联网
我有2个类,一个用于通过缓存访问数据库和子类.我可以更改两个类的源代码,但是有许多结构不同的类,因此我正在寻找一种方法来生成通用解决方案,以帮助我仅拦截用Attribute标记的方法或其他方法.
这是一个例子
public class BaseClass
{
[MyAttribute]
public virtual MyEntity[] GetAll() {}
[MyAttribute]
public virtual MyEntity GetByKey(int key) {}
[MyAttribute]
public virtual void GetByName(string name) {}
}
public class ChildClass : BaseClass
{
public override MyEntity GetByKey(int key)
{
if(key > 100)
return GetCachedEntity(key);
return base.GetByKey(key);
}
}
public class MyInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
// Here I can check any required conditions to decide on the way of processing
var myCondition = invocation.Method.GetCustomAttributes(false).Any(a => a is MyAttribute);
if(myCondition)
{
// extra logic for marked methods
}
invocation.Proceed();
}
}
public static class MyProxyFactory
{
private static readonly ProxyGenerator proxyGenerator = new ProxyGenerator();
// here is my generic proxy factory which I want to use for creating proxies for ChildClass objects and another objects that contains similar logic
public static TInterface CreateProxy<TInterface>(TInterface concreteObject)
where TInterface : class
{
var proxy = proxyGenerator.CreateInterfaceProxyWithTarget(concreteObject, ProxyGenerationOptions.Default, new MyInterceptor());
return proxy;
}
}
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public class MyAttribute : Attribute {}
我正在尝试对myCondition使用invocation.Method.GetCustomAttributes()并仅标记基类方法,但是问题是,当ChildClass.GetByKey()调用基类方法时,它不会被MyInterceptor.Intercept()方法拦截.
在此示例中,我可以将分解替换为继承,但随后需要在ChildClass中实现GetAll和GetByName方法,并且此解决方案将不是通用的.
如何更改ProxyGenerator设置或CreateProxy()方法来解决我的问题?
var realObject = new ChildClass();
var proxyObject = MyProxyFactory.CreateProxy(realObject);
// extra logic should be executed
proxyObject.GetAll();
// extra logic should be executed
proxyObject.GetByKey(99);
// extra logic should not be executed
proxyObject.GetByKey(101);
解决方法:
一个base.Method调用故意不尝试查找比该类的基类更进一步继承关系的方法重载.代理不会执行幻想,它会覆盖子类中的方法,并依赖于虚拟调用来到达代理而不是其基本实现.或者,如果它是包装代理,则仅拦截外部呼叫-我不知道您使用的代理类型的详细信息.
因此,基本上,一旦编写base.Method,就不会期望发生任何子类魔术.如果需要在层次结构内部的子父交互中进行拦截,则需要重新访问设计方法.
标签:system-reflection,castle-dynamicproxy,c 来源: https://codeday.me/bug/20191110/2013410.html