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

标签 dependency-injection autofac circular-dependency property-injection

有关 Circular References 的 autofac wiki 页面说使用:

cb.Register<DependsByProp>().OnActivated(ActivatedHandler.InjectUnsetProperties);

但是ActivatedHandler在2.4.5中似乎不再存在了。在源代码中挖掘,我找到了该类的实现,因此我将方法实现放入 OnActivated 中。不幸的是,这仍然不起作用。

我在这里整理了一个最小的重现,看起来就像 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);
    }
}

在尝试解决时,此代码仍然会引发堆栈溢出异常。我缺少什么?让 Autofac 处理循环依赖的正确方法是什么?

最佳答案

circular dependencies 的 Autofac 文档状态:

Note, it doesn't make sense to set up this scenario if both classes are registered with Factory scope.

您的 MVM 注册都是 InstancePerDependency(以前称为 FactoryScope),因此此语句适用于你的场景。结果,您陷入了创建 M 和 VM 实例的无限循环。

如果您希望注入(inject)的 VM 属性采用您解析的 M相同实例,您应该更改 的生命周期>MInstancePerDependency 以外的其他内容(例如 SingleInstance)。如下所示:

builder.RegisterType<M>().PropertiesAutowired(true).SingleInstance();

注意:我还使用了更新的 PropertiesAutowired(true) 扩展方法。您可以使用它来代替重现中的 OnActivated 代码。

如果您不希望每个应用有一个 M 实例,您可以设置 LifetimeScope并使用InstancePerLifetimeScope

关于dependency-injection - 如何使用 Autofac 2.4.5 处理循环引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6186206/

相关文章:

c# - 需要当前 Request.Url 的类型的 Ninject 绑定(bind)

AngularJs 拦截器的循环依赖

dependency-injection - CDI 注入(inject)回路

c# - Autofac:如何传递参数以在 Razor 页面中注册

Angular 圆形模块导入

c# - 在 Controller 的构造函数之外使用依赖注入(inject)

交响乐 4.2+ : Replacement for ContainerAwareCommand's getContainer->get()

security - Symfony2 : Injecting @security. 获取当前用户的上下文。如何避免 "ServiceCircularReferenceException"?注入(inject)整个容器?

c# - 找出哪个模块注册了类型

c# - Autofac、IDisposable 和在某些情况下手动调用 .Resolve