9

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

我已经看到在其他 DI 框架中使用这种方法破坏了循环依赖关系——这是 Structuremap 的问题还是我做错了什么?

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

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

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

  • 构造一个B的实例,“b”
  • 构造 A 的实例“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 ...”

4

3 回答 3

6

StructureMap 也可以通过使用延迟分辨率的解决方法来处理双向情况。

如果你有一个简单的情况,比如ClassA依赖于ClassBClassB依赖于ClassA,那么你可以选择其中之一并将依赖转换为惰性依赖。这种方式对我有用,并且该错误再也没有出现过..

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/

于 2016-10-29T20:02:02.727 回答
3

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

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

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

于 2010-05-06T18:32:07.537 回答
1

StructureMap 可能正在执行Setter 注入,它将在它正在解析的对象上填充公共可设置属性。根据文件,

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

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

编辑:我看到你有。在您的实例中,因为 B 注入了 A[],StructureMap 必须为需要 A[] 的 B 解析每个 A 的依赖关系,依此类推...

于 2010-05-06T15:43:31.033 回答