代码之家  ›  专栏  ›  技术社区  ›  Andy

structuremap中的循环依赖项-是否可以通过属性注入中断它们?

  •  9
  • Andy  · 技术社区  · 14 年前

    我在structuremap中得到了最简单的循环依赖——类A在其构造函数中依赖于类B,而类B在其构造函数中依赖于类A。为了打破依赖关系,我让类B将类A作为一个属性,而不是一个构造函数参数,但是structuremap仍然会抱怨。

    我已经看到在其他DI框架中使用这个方法打破了循环依赖性——这是结构映射的问题还是我做错了什么?

    编辑: 我应该提到,类B的属性是类A实例的数组,连接方式如下:

    x.For<IB>().Singleton().Use<B>().Setter(y => y.ArrayOfA).IsTheDefault();
    

    为了澄清,我希望发生以下事件序列:

    • 构造B的实例,“B”
    • 构造“a”的实例,将“b”注入其构造函数
    • 将“b.arrayofa”设置为[“a”]

    如果可能的话,我希望所有这些都能通过自动布线来实现…

    编辑2: 下面是一个使用显式连接的简化示例:

    interface ILoader { }
    interface ILoaderManager { }
    
    class Loader : ILoader
    {
        public Loader(ILoaderManager lm) { }
    }
    class LoaderManager : ILoaderManager
    {
        public ILoader Loader { get; set; } // Was an array, but same circular dependency appears here
    }
    
    ObjectFactory.Configure
    (
        x =>
        {
            x.For<ILoader>.Singleton().Use<Loader>();
            x.For<ILoaderManager>().Singleton().Use<LoaderManager>().OnCreation((c, a) => a.Loader = c.GetInstance<ILoader>());
        }
    );
    

    验证配置会导致“使用requestedType检测到双向依赖性问题:ioctest2.iloader…”

    3 回复  |  直到 5 年前
        1
  •  3
  •   Joshua Flanagan    14 年前

    你能得到的最接近的是这样的:

    x.For<IB>().Use<B>()
        .OnCreation((ctx, instance) =>
        {
            instance.ArrayOfA = new IA[] {new A(instance) };
        });
    

    如果 A 具有要从容器中解析的其他依赖项,可以从中检索它们 ctx 在onCreation lambda中。

        2
  •  6
  •   Javier    5 年前

    structuremap还可以通过使用惰性分辨率的变通方法来处理双向情况。

    如果你有一个简单的情况 ClassA 这取决于 ClassB 乙类 这取决于 等级 ,然后您可以选择其中一个,并将依赖项转换为惰性依赖项。这种方法对我很有效,而且那个错误再也没有出现过。

    public class ClassA
    {
        private readonly Lazy<IClassB> _classB;
    
        public ClassA(Lazy<IClassB> classB)
        {
            _classB = classB;
        }
    
        public IClassB ClassB => _classB.Value;
    }
    
    public class ClassB 
    {
        public IClassA _classA { get; set; }
    
        public ClassB (IClassA classA)
        {
            _classA = classA;
        }
    }
    

    更多信息: http://structuremap.github.io/the-container/lazy-resolution/

        3
  •  0
  •   statenjason    14 年前

    结构映射可能正在执行 Setter Injection 它将填充正在解析的对象的公共可设置属性。根据文件,

    默认情况下,所有公共“setter”都是可选的,这意味着只有在为特定实例显式配置这些setter时,才会设置它们。

    那么,您是否偶然设置了要自动连接的属性?如果是这样,您仍然会遇到循环依赖问题。

    编辑:我看到了。在您的实例中,因为B注入了一个[],所以structureMap必须解析每个A对需要一个[]的B的依赖关系,依此类推…