代码之家  ›  专栏  ›  技术社区  ›  Oliver Hanappi

Castle Windsor:如何检索特定实例的代理?

  •  3
  • Oliver Hanappi  · 技术社区  · 16 年前

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

    是否有一种方法可以获取代理实例,该实例在实际实现中表示实际实现?

    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();
        }
    }
    

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

    顺致敬意,
    奥利弗·哈纳皮

    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)让视图了解其表示模型。
    现在的问题是,尽管解析后的IPPresentationModel是一个代理,但SetModel方法只能得到真正的实现。因此,当视图调用表示模型上的方法时,不会触发拦截器。

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

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

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

    1 回复  |  直到 16 年前
        1
  •  3
  •   Krzysztof Kozmic    16 年前

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

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