定义动态代理的基类或基功能(例如Castle、LinFu)

发布于 2024-08-30 17:01:33 字数 581 浏览 6 评论 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 使用的任何常见代理生成器中完成吗?

I've asked this in the NHibernate forumns but I think this is more of a general question. NHibernate uses proxy generators (e.g. Castle) to create its proxy.

What I'd like to do is to extend the proxy generated so that it implements some of my own custom behaviour (i.e. a comparer). I need this because the following standard .NET behaviour fails to produce the correct results:

//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

If my comparer was implemented by AP (i.e. do id's match) then collection.Contains(AP) would return true, as I'd expect if proxies were implicit. (NB: For those who say NH inherits from your base class, then yes it does, but NH can also inherit from an interface - which is what we're doing)

I'm not at all sure this is possible or where to start. Is this something that can be done in any of the common proxy generators that NH uses?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

━╋う一瞬間旳綻放 2024-09-06 17:01:33

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

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

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

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

With Castle DynamicProxy you have few choices.

First is to provide the IComparer<T> as one of additionalInterfacesToProxy when creating the proxy. The interface will have no actual implementation to proceed to, so you need to provide an interceptor that instead of calling Proceed will provide the actual logic for the methods.

Alternatively you can provide a mixin, which implements the required interface and provides the logic you need. Notice you most likely will need to pass the mixin reference back to the proxy or its target.

Third option, available only for interface proxies is to set the base class proxyGenerationOptions.BaseClassForInterfaceProxy = typeof(SomethingImplementingComparer);

っ〆星空下的拥抱 2024-09-06 17:01: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 来说非常容易做到,因为每个代理实例都它生成需要一个拦截器。如果更改拦截器,则可以自动更改代理的行为。我希望这有帮助。

This kind of behavior is possible with LinFu.DynamicProxy, but you would have to replace the interceptor provided by NHibernate with your own custom interceptor that delegates it calls back to the original interceptor:

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;

This is pretty easy to do with LinFu since every proxy instance that it generates requires an interceptor. If you change the interceptor, then you can automatically change a proxy's behavior. I hope that helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文