0

我在 NHibernate 论坛上问过这个问题,但我认为这是一个普遍的问题。NHibernate 使用代理生成器(例如 Castle)来创建它的代理。

我想做的是扩展生成的代理,以便它实现我自己的一些自定义行为(即比较器)。我需要这个,因为以下标准 .NET 行为无法产生正确的结果:

//object AC is a concrete class
collection.Contains(AC) = true

//object AP is a proxy with the SAME id and therefore represents the same instance as concrete AC
collection.Contains(AP) = false

如果我的比较器是由 AP 实现的(即做 id 的匹配),那么 collection.Contains(AP) 将返回 true,正如我所期望的那样,如果代理是隐式的。(注意:对于那些说 NH 从您的基类继承的人,是的,它确实如此,但 NH 也可以从接口继承——这就是我们正在做的)

我完全不确定这是可能的或从哪里开始。这可以在 NH 使用的任何常见代理生成器中完成吗?

4

2 回答 2

2

使用 Castle DynamicProxy,您几乎没有选择。

首先是在创建代理时提供IComparer<T>as one 。additionalInterfacesToProxy该接口将没有实际的实现可以继续,因此您需要提供一个拦截器,而不是调用Proceed它将为方法提供实际逻辑。

或者,您可以提供一个 mixin,它实现所需的接口并提供您需要的逻辑。请注意,您很可能需要将 mixin 引用传递回代理或其目标。

第三个选项,仅适用于接口代理是设置基类proxyGenerationOptions.BaseClassForInterfaceProxy = typeof(SomethingImplementingComparer);

于 2010-05-03T05:46:39.437 回答
0

这种行为在 LinFu.DynamicProxy 中是可能的,但您必须将 NHibernate 提供的拦截器替换为您自己的自定义拦截器,该拦截器将其委托回原始拦截器:

var yourProxiedInterfaceInstance = ...

// Get the Interceptor that NHibernate uses

var proxy = (IProxy)yourProxiedInterfaceInstance;

var interceptor = proxy.Interceptor;

// You'll need to create a decorator class around the IInterceptor interface
var yourInterceptor = new SomeCustomInterceptor(interceptor); 

// Replace the interceptor here
proxy.Interceptor = yourInterceptor;

使用 LinFu 很容易做到这一点,因为它生成的每个代理实例都需要一个拦截器。如果您更改拦截器,那么您可以自动更改代理的行为。我希望这会有所帮助。

于 2010-05-02T22:12:33.090 回答