【问题标题】:Castle Windsor: How to retrieve proxy for specific instance?温莎城堡:如何检索特定实例的代理?
【发布时间】:2010-11-27 11:26:38
【问题描述】:

我在我的项目中使用 Castle Windsor。一些注册的组件被拦截。因为组件是通过接口注册的,Castle Windsor 创建了接口代理(Castle Windsor 创建了一个独立的类型,它实现了接口并通过使用组合委托给真正的实现)。不幸的是,您无法在接口的实际实现中执行方法,因为代理会被绕过。

有没有办法在实际实现中获取代表实际实现的代理实例?

这是我想要实现的一个示例。我想总是拦截 Get 方法。请不要使用其他方法来重构此示例,因为这不是我的生产代码,而只是为了演示而发明的东西。

public interface IProvider
{
    bool IsEmpty { get; }
    object Get();
}

public class ProxyBypassingProvider : IProvider
{
    public bool IsEmpty
    {
        // Calls method directly, not through the proxy.
        get { return Get() == null; }
    }

    public object Get()
    {
        return new Object();
    }
}

public class InterceptedProvider : IProvider
{
    private IProvider _this; // Should hold the proxy instance.

    public bool IsEmpty
    {
        // Calls method through proxy.
        get { return _this.Get() == null; }
    }

    public object Get()
    {
        return new Object();
    }
}

如何将字段 _this 设置为代理实例?

最好的问候
奥利弗·哈纳皮

PS:这是一个真实的例子。

public interface IPresentationModel
{
    IView View { get; }
}

public interface IView
{
    void SetModel(IPresentationModel model);
}

public PresentationModel : IPresentationModel
{
    public IView View { get; private set; }

    public PresentationModel(IView view)
    {
        View = view;
        View.SetModel(this);
    }
}

我正在解决一个瞬态演示模型。它会注入一个瞬态视图。因为视图需要知道表示模型,所以表示模型调用 IView.SetModel(this) 让视图知道它的表示模型。
现在的问题是,虽然解析的 IPresentationModel 是一个代理,但 SetModel 方法只获得真正的实现。因此,当视图调用表示模型上的方法时,不会触发任何拦截器。

到目前为止,我找到的唯一解决方案是在解析了我的演示模型后手动设置视图的演示模型。

var model = _container.Resolve<IPresentationModel>();
model.View.SetModel(model);

我认为,这个解决方案并没有真正解决得很好。

【问题讨论】:

  • 看起来你把事情复杂化了,但我不确定,因为我不完全理解你想要实现的目标......你能发布更多关于你的潜在问题的细节吗?
  • 嗨!我不认为,我让事情变得更复杂。我只想使用拦截器。当某些对象解析 IProvider 时,它不会获得已注册组件的实例,而是获得实现 IProvider 的动态创建的类的实例。此类将每个请求转发给真正的实现,但会拦截请求。当真实实现调用接口方法时,调用不会经过动态创建的代理,而是直接调用真实方法。因此不会调用任何拦截器。希望,现在更清楚一点;)

标签: c# proxy castle-windsor castle-dynamicproxy


【解决方案1】:

这就是所谓的“泄露这个”问题,对于接口代理没有很好的解决方法。

您提到的后期合成步骤可能是最好的解决方案。您可以使用 Tuna 的 OnCreateFacility - 它已烘焙到主干中,或者如果您不想在主干上运行,您可以从存储库中复制代码并与 v2.0 一起使用。

【讨论】:

  • 我想,解释起来太复杂了,为什么我需要这个。我们可以专注于这个问题吗?
  • 好的,专注于这个问题 - 你不能。但同样,做你所做的事情的原因是什么?如果您不想公开谈论它,请给我发电子邮件。我真的很好奇。
  • 啊,这可能对我有帮助。我能以某种方式拦截温莎城堡的解析或代理过程吗?
  • 你的意思是:tunatoksoz.com/post/…(不幸的是,它只在后备箱中......它是在 v2.0 版本之后添加的)。
  • 感谢您的帮助,我找到了一个可以接受的解决方案:我编写了一个订阅 ComponentCreated 事件的小工具。我定义了一个接口,该接口具有代理实例的属性和初始化方法。如果创建的组件实现了接口,则代理或组件本身将被分配给该属性,然后将调用initialize方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多