城堡DynamicProxy:进行代理的接口时,如何代理等于? [英] Castle DynamicProxy : How to Proxy Equals when proxying an interface?
问题描述
我需要使用城堡DynamicProxy代理接口,提供它的一个实例ProxyGenerator.CreateInterfaceProxyWithTarget。我还需要确保调用的Equals,GetHash code和toString击中的具体实例的方法,我想过去,我不能得到那个工作。
I need to use Castle DynamicProxy to proxy an interface by providing an instance of it to ProxyGenerator.CreateInterfaceProxyWithTarget. I also need to make sure that calls to Equals, GetHashCode and ToString hits the methods on the concrete instance, that I am passing, and I can't get that to work.
在换句话说,我想这个小样本打印真
两次,而实际上它打印真,假
:
In other words, I'd like this small sample to print True
twice, while in fact it prints 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?怎么样?
Is this possible with DynamicProxy ? How ?
推荐答案
这是一个有点棘手。 <一href="http://stw.castleproject.org/Tools.DynamicProxy-Introduction.ashx#Interception_pipeline_5">Take看看文档的代理是如何工作的。接口代理包装一个对象,并拦截调用指定的接口(S)。由于等于
是不是该接口的第二个呼叫到等于在比较代理的一部分,而不是他们的目标。
This is a bit tricky. Take a look at documentation on how proxies work. Interface proxies wrap an object and intercept calls to designated interface(s). Since Equals
is not part of that interface the second call to equals is comparing proxies, not their targets.
那么,什么提供了实现第二个等于
打电话?
So what provides the implementation for the second Equals
call?
代理只是另一个类实现你的 IDummy
接口。正如任何类它也有一个基类,而这对基实现等于
被调用的。这个基类是默认的 System.Object的
Proxy is just another class implementing your IDummy
interface. As any class it also has a base class, and that's the base implementation of Equals
that gets invoked. This base class is by default System.Object
我希望你现在看到这是怎么回事。解决这一问题的办法是告诉代理实现,将转发呼叫代理目标有些代理知道基类。其实现的一部分可能是这样的:
I hope you see now where this is going. Solution to this problem is to tell proxy to implement some proxy aware base class that will forward the calls to proxy target. Part of its implementation might look like this:
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
}
现在你只需要,而不是默认的指示代理生成器使用这个基类的接口代理。
Now you only need to instruct the proxy generator to use this base class for your interface proxies, instead of the default.
var o = new ProxyGenerationOptions();
o.BaseTypeForInterfaceProxy = typeof(ProxyBase);
IDummy firstProxy = g.CreateInterfaceProxyWithTarget(first, o);
IDummy secondProxy = g.CreateInterfaceProxyWithTarget(second, o);
这篇关于城堡DynamicProxy:进行代理的接口时,如何代理等于?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!