如何使用Autofac 2.4.5处理循环引用?

Ant*_*nts 5 dependency-injection circular-dependency autofac property-injection

关于循环引用的autofac wiki页面说使用:

cb.Register<DependsByProp>().OnActivated(ActivatedHandler.InjectUnsetProperties);
Run Code Online (Sandbox Code Playgroud)

但看起来ActivatedHandler在2.4.5中不再存在了.在源代码中挖掘,我找到了该类的实现,因此我在OnActivated中添加了方法实现.不幸的是,它仍然无效.

我在这里整理了一个最小的repro,看起来就像Wiki页面上的内容.

class M
{
    public VM VM { get; set; }

    public M()
    {
    }
}

class VM
{
    public VM(M m)
    {
    }
}

[Fact]
void CanResolveCircular()
{
    ContainerBuilder builder = new ContainerBuilder();

    builder.RegisterType<VM>();
    builder.RegisterType<M>().OnActivated(e => e.Context.InjectUnsetProperties(e.Instance));

    using (var container = builder.Build())
    {
        var m = container.Resolve<M>();
        Assert.NotNull(m);
    }
}
Run Code Online (Sandbox Code Playgroud)

当尝试Resolve时,此代码仍会引发堆栈溢出异常.我错过了什么?让Autofac处理循环依赖的正确方法是什么?

ben*_*ruk 7

循环依赖关系的Autofac文档说明:

请注意,如果两个类都使用Factory范围注册,则设置此方案没有意义.

MVM注册都是InstancePerDependency(以前称为FactoryScope),因此此声明适用于您的方案.因此,您将无休止地创建M和VM实例.

如果你想注入的财产VM采取相同的实例M,你解决,你应该的寿命更改M为以外的东西InstancePerDependency(如SingleInstance).如下所示:

builder.RegisterType<M>().PropertiesAutowired(true).SingleInstance();
Run Code Online (Sandbox Code Playgroud)

注意:我也在使用更新的PropertiesAutowired(true)扩展方法.您可以使用它代替repro中的OnActivated代码.

如果您不想要M每个应用程序的单个实例,则可以设置LifetimeScope并使用InstancePerLifetimeScope.


MeT*_*tus 5

对于任何感兴趣的人来说,这是一种新的方式:

class DependsByProp1
{
    public DependsByProp2 Dependency { get; set; }
}

class DependsByProp2
{
    public DependsByProp1 Dependency { get; set; }
}

// ...

var cb = new ContainerBuilder();
cb.RegisterType<DependsByProp1>()
      .InstancePerLifetimeScope()
      .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);
cb.RegisterType<DependsByProp2>()
      .InstancePerLifetimeScope()
      .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);
Run Code Online (Sandbox Code Playgroud)

财产/财产依赖