Castle windsor Windsor如何为每次解析调用创建一个组件?

Castle windsor Windsor如何为每次解析调用创建一个组件?,castle-windsor,Castle Windsor,考虑以下类别: public interface IView { /// <summary> /// Ignore this (its only for the assertion) /// </summary> ITask Task { get; } } public class ViewA : IView { private readonly ITask _task; public ViewA(ITask task)

考虑以下类别:

public interface IView
{
    /// <summary>
    /// Ignore this (its only for the assertion)
    /// </summary>
    ITask Task { get; }
}

public class ViewA : IView
{
    private readonly ITask _task;

    public ViewA(ITask task)
    {
        _task = task;
    }

    public ITask Task
    {
        get { return _task; }
    }
}
public class ViewB : IView
{
    private readonly ITask _task;

    public ViewB(ITask task)
    {
        _task = task;
    }

    public ITask Task
    {
        get { return _task; }
    }
}

public class ViewManager
{
    private readonly List<IView> _views;

    public ViewManager(IView[] views)
    {
        _views = new List<IView>(views);
    }

    public ReadOnlyCollection<IView> Views
    {
        get { return new ReadOnlyCollection<IView>(_views); }
    }
}
最后,我要实现的目标是:

    [Fact]
    public void Configure_TwoServicesWithDependencyToTransientComponent_BothShareComponent()
    {
        // arrange
        var windsorContainer = new WindsorContainer();

        windsorContainer.Kernel.Resolver.AddSubResolver(new ArrayResolver(windsorContainer.Kernel));

        windsorContainer.Register(Component.For<ITask>()
            .ImplementedBy<TaskWithNoDependencies>()
            .Named("task")
            .LifeStyle.Transient);

        windsorContainer.Register(Component.For<IView>().ImplementedBy<ViewA>().LifeStyle.Transient);
        windsorContainer.Register(Component.For<IView>().ImplementedBy<ViewB>().LifeStyle.Transient);

        windsorContainer.Register(Component.For<ViewManager>()
            .LifeStyle.Transient);

        // act
        ViewManager service = windsorContainer.Resolve<ViewManager>();

        // assert
        Assert.Same(service.Views[0].Task, service.Views[1].Task);
    }
在解析ViewManager时,如何使Windsor创建ITask的实例,使其由ViewA和ViewB共享?我尝试了以下方法,但无效:

        windsorContainer.Register(Component.For<ViewManager>()
            .DynamicParameters((k, d) =>
                                   {
                                       d["task"] = k.Resolve<ITask>();

                                   })
            .LifeStyle.Transient);
你为什么要这样做?您试图做的是将实例绑定到依赖关系树的上下文。也许上下文更广泛,比如web请求?你为什么要这样做

这是可能的,但我知道用温莎2.5做这件事的干净方法。以前的版本可能需要一些技巧


我找到了一个解决方案,但我希望有人能提出更好的解决方案。请对所选解决方案提出一些批评:

    [Fact]
    public void Configure_TwoServicesWithDependencyToTransientComponent_BothShareComponent()
    {
        // arrange
        var windsorContainer = new WindsorContainer();

        windsorContainer.Kernel.Resolver.AddSubResolver(new ArrayResolver(windsorContainer.Kernel));

        windsorContainer.Register(Component.For<ITask>().ImplementedBy<TaskWithNoDependencies>().LifeStyle.Custom(typeof(PerScopeOrTransientLifestyleManager)));

        windsorContainer.Register(Component.For<IView>().ImplementedBy<ViewA>().LifeStyle.Transient);
        windsorContainer.Register(Component.For<IView>().ImplementedBy<ViewB>().LifeStyle.Transient);

        windsorContainer.Register(Component.For<ViewManager>()
            .LifeStyle.Transient);

        // act
        ViewManager service;

        using (new LifeStyleScope())
        {
            service = windsorContainer.Resolve<ViewManager>();
        }

        // assert
        Assert.Same(service.Views[0].Task, service.Views[1].Task);
    }
我做了两件事:

创建了一个定制的生活方式管理器,该管理器增加了这样一种能力:组件在生活方式范围之外是暂时的,而在生活方式范围内是单独的

创建了一个生活方式范围,可用于指定上下文边界


这个解决方案有一点我不喜欢,那就是您必须从呼叫站点了解上下文问题。我可以通过将生活方式范围移动到viewmanager中来抽象这一点,但是viewmanager需要有一个ioc依赖项,这将在测试viewmanager时需要一些额外的存根。

这是一个winforms应用程序,我没有任何静态web请求上下文或任何东西可以绑定它。上下文边界是通过解析另一个ServiceWithTaskDependency定义的。我可以访问最新版本的Windsor,所以请告诉我干净的解决方案:-好的,但为什么它是上下文边界?您希望在这两个对象之间而不是在其他对象之间共享实例的原因是什么?它们之间的关系是什么?我有一个ViewManager,它将视图列表作为输入参数。视图必须共享一些组件,因为它们必须响应彼此之间的更改。两个不同ViewManager中的视图不应共享上述组件。因此,解析ViewManager表示上下文边界。基本上,ViewManagers最终位于不同的UI容器中。如果有帮助的话,我可以给你发一些代码。好的,那么如何划分视图管理器呢?他们有什么义务?屏幕?贝壳?还有什么?ViewManager由一个名为LayoutContainer的UI容器在内部使用。可以向主画布添加任意数量的Layoutcontainers。因此,关系是:一个屏幕,多个布局容器,每个布局容器:一个ViewManager。