我需要使用 Castle DynamicProxy 通过向 ProxyGenerator.CreateInterfaceProxyWithTarget 提供接口实例来代理接口。我还需要确保对 Equals、GetHashCode 和 ToString 的调用会命中我正在传递的具体实例上的方法,但我无法使其正常工作。
换句话说,我想要打印这个小样本True
两次,而实际上它打印了True,False
:
using System;
using Castle.Core.Interceptor;
using Castle.DynamicProxy;
public interface IDummy
{
string Name { get; set; }
}
class Dummy : IDummy
{
public string Name { get; set; }
public bool Equals(IDummy other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Equals(other.Name, Name);
}
public override bool Equals(object obj)
{
return Equals(obj as IDummy);
}
}
class Program
{
static void Main(string[] args)
{
var g = new ProxyGenerator();
IDummy first = new Dummy() {Name = "Name"};
IDummy second = new Dummy() {Name = "Name"};
IDummy firstProxy = g.CreateInterfaceProxyWithTarget(first, new ConsoleLoggerInterceptor());
IDummy secondProxy = g.CreateInterfaceProxyWithTarget(second, new ConsoleLoggerInterceptor());
Console.WriteLine(first.Equals(second));
Console.WriteLine(firstProxy.Equals(secondProxy));
}
}
internal class ConsoleLoggerInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("Invoked " + invocation.Method.Name);
}
}
这可以通过 DynamicProxy 实现吗?如何 ?
这有点棘手。看一下文档关于代理如何工作。接口代理包装对象并拦截对指定接口的调用。自从Equals
不是该接口的一部分,第二次调用 equals 是比较代理,而不是它们的目标。
那么第二个的实现是什么呢?Equals
call?
代理只是另一个实现你的类IDummy
界面。与任何类一样,它也有一个基类,这是Equals
被调用。该基类默认为System.Object
我希望你现在明白事情的发展方向了。此问题的解决方案是告诉代理实现一些代理感知基类,该基类会将调用转发到代理目标。其部分实现可能如下所示:
public class ProxyBase
{
public override bool Equals(object obj)
{
var proxy = this as IProxyTargetAccessor;
if (proxy == null)
{
return base.Equals(obj);
}
var target = proxy.DynProxyGetTarget();
if (target == null)
{
return base.Equals(obj);
}
return target.Equals(obj);
}
// same for GetHashCode
}
现在您只需指示代理生成器为您的接口代理使用此基类,而不是默认的。
var o = new ProxyGenerationOptions();
o.BaseTypeForInterfaceProxy = typeof(ProxyBase);
IDummy firstProxy = g.CreateInterfaceProxyWithTarget(first, o);
IDummy secondProxy = g.CreateInterfaceProxyWithTarget(second, o);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)