gpt4 book ai didi

c# - 城堡动态代理 : How to Proxy Equals when proxying an interface?

转载 作者:可可西里 更新时间:2023-11-01 09:06:51 27 4
gpt4 key购买 nike

我需要使用 CaSTLe DynamicProxy 来代理接口(interface),方法是向 ProxyGenerator.CreateInterfaceProxyWithTarget 提供接口(interface)实例。我还需要确保对 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 可以吗?怎么样?

最佳答案

这有点棘手。 Take a look at documentation关于代理如何工作。接口(interface)代理包装一个对象并拦截对指定接口(interface)的调用。由于 Equals 不是该接口(interface)的一部分,因此对 equals 的第二次调用是比较代理,而不是它们的目标。

那么是什么为第二个 Equals 调用提供了实现?

Proxy 只是实现您的IDummy 接口(interface)的另一个类。与任何类一样,它也有一个基类,这是被调用的 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
}

现在您只需要指示代理生成器将此基类用于您的接口(interface)代理,而不是默认值。

var o = new ProxyGenerationOptions();
o.BaseTypeForInterfaceProxy = typeof(ProxyBase);
IDummy firstProxy = g.CreateInterfaceProxyWithTarget(first, o);
IDummy secondProxy = g.CreateInterfaceProxyWithTarget(second, o);

关于c# - 城堡动态代理 : How to Proxy Equals when proxying an interface?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2969274/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com