我已经在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实现的(即do id的匹配),那么collection.Contains(AP)将返回true,就像我期望的那样,如果代理是隐式的。(注意:对于那些说NH继承您的基类的人来说,是的,它确实是继承的,但NH也可以从接口继承--这就是我们正在做的)
我根本不确定这是不是可能的,也不知道从哪里开始。这是可以在NH使用的任何公共代理生成器中完成的吗?
发布于 2010-05-03 06:12:33
使用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-03 13:46:39
使用Castle DynamicProxy时,您几乎没有选择。
第一个是在创建代理时将IComparer<T>作为additionalInterfacesToProxy之一提供。接口将没有实际的实现,因此您需要提供一个拦截器,而不是调用Proceed,它将为方法提供实际的逻辑。
或者,您可以提供一个mixin,它实现所需的接口并提供所需的逻辑。请注意,您很可能需要将混合引用传递回代理或其目标。
仅适用于接口代理的第三个选项是设置基类proxyGenerationOptions.BaseClassForInterfaceProxy = typeof(SomethingImplementingComparer);
https://stackoverflow.com/questions/2754400
复制相似问题