0

我有这样写的一堆类:温莎短暂生活方式的循环依赖组件

public class MyService1 { 
    public MyService1(MyService1Settings settings, <service-dependent list of dependencies filled by Windsor>) { ... } 
} 

被登记在温莎这样的:

container.Register(
    ... 
    Component.For<MyService1>().LifestyleTransient(), 
    Component.For<MyService2>().LifestyleTransient(), 
    ... 
); 

容器没有按”没有任何MyServiceXSettings类型注册,所以获得服务的唯一方法就是像这样从容器中解析它:

TService service = windsorContainer.Resolve<TService>(new { settings }); 

事情是,根据settings对象中的参数,其中一个服务尝试使用不同的设置对象获取其类型的另一个实例。

东西线沿线的:

public class MyService2 { 
    public MyService2(MyService2Settings settings, <service-dependent list of dependencies filled by Windsor>) 
    { 
     this.uplink = settings.Counter == 1 
      ? new AnotherUplink() 
      : new RecursiveUplink(
       container.Resolve<MyService2>(new { 
        settings = new MyService2Settings(settings.Counter - 1) 
       }); 
    } 
} 

这递归依赖性链是有限的(并且是大约6实例深),但是当第一个服务尝试得到另一个温莎抛出一个异常,指出这是循环依赖。

我已经宣传所有服务为Transient生活方式并向他们请求自定义参数。我能至少指定递归的最大允许深度吗?或者我错过了另一种可以做到的方式?

另一个需求:我不能使用类型化的工厂,因为我有很多不同类型的服务,所以为这些服务单独生成许多工厂接口将是不受欢迎的。

回答

1

容器没有任何注册的MyServiceXSettings类型, 所以要得到服务的唯一方法是从容器解决它像 这样:

您也可以使用专用SubResolver或组件注册期间的DependsOn。

在构造函数中执行代码(而不是简单的变量赋值)是一种气味,甚至在使用容器时最糟糕:它绝对不应该泄漏到应用程序层中。乍看之下,您似乎只使用设置来选择构造函数中的适当组件:应该在CompositionRoot中完成,使用TypedFactory或者也可以使用naming convention(您可能有多个组件注册了相同的intercace ,但给定的参数名称驱动组件选择)

0

按照this answer,我去懒惰的决议。

/// <summary> 
/// Represents single component instance producer. 
/// </summary> 
/// <typeparam name="TComponent">type of the component to create</typeparam> 
public interface IComponentCreator<TComponent> 
{ 
    /// <summary> 
    /// Gets the created component. 
    /// </summary> 
    TComponent Component { get; } 
} 

/// <summary> 
/// Creates the component only when it's first requested. 
/// </summary> 
/// <typeparam name="TComponent">type of the component to create</typeparam> 
public class LazyCreator<TComponent> : IComponentCreator<TComponent> 
{ 
    private readonly Func<TComponent> creatingFunction; 
    private bool created; 
    private TComponent component; 

    public LazyCreator(Func<TComponent> creatingFunction) 
    { 
     this.creatingFunction = creatingFunction; 
    } 

    public TComponent Component 
    { 
     get 
     { 
      if (!created) 
      { 
       component = creatingFunction(); 
       created = true; 
      } 

      return component; 
     } 
    } 
} 

/// <summary> 
/// Returns already created component. 
/// </summary> 
/// <typeparam name="TComponent">type of the component</typeparam> 
public class ComponentContainer<TComponent> : IComponentCreator<TComponent> 
{ 
    private readonly TComponent component; 

    public ComponentContainer(TComponent component) 
    { 
     this.component = component; 
    } 

    public TComponent Component 
    { 
     get { return component; } 
    } 
}