我在NHibernate forumns中问过这个问题,但我认为这更像是一个普遍的问题。 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使用的任何常见代理生成器中完成吗?
答案 0 :(得分:2)
使用Castle DynamicProxy,你几乎没有选择。
首先是在创建代理时将IComparer<T>
提供为additionalInterfacesToProxy
之一。接口将没有实际的实现,因此您需要提供一个拦截器而不是调用Proceed
将为方法提供实际的逻辑。
或者,您可以提供mixin,它实现所需的接口并提供您需要的逻辑。请注意,您很可能需要将mixin引用传递回代理或其目标。
仅适用于接口代理的第三个选项是设置基类proxyGenerationOptions.BaseClassForInterfaceProxy = typeof(SomethingImplementingComparer);
答案 1 :(得分: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非常容易,因为它生成的每个代理实例都需要一个拦截器。如果更改拦截器,则可以自动更改代理的行为。我希望有所帮助。