如何使用 Autofac 2.4.5 处理循环引用?
关于循环引用的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 处理循环依赖的正确方法是什么?
The autofac wiki page about Circular References says to use:
cb.Register<DependsByProp>().OnActivated(ActivatedHandler.InjectUnsetProperties);
But it looks like ActivatedHandler does not exist anymore in 2.4.5. Digging around in the source, I found the implementation of that class, and so I put in the method implementation in the OnActivated instead. Unfortunately, it this still doesn't work.
I've put together a minimal repro here that looks like what was on the Wiki page.
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);
}
}
This code still throws a stack overflow exception as a Resolve is attempted. What am I missing? What is the correct way to get Autofac to handle circular dependencies?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
循环依赖项的 Autofac 文档指出:
您的
M
和VM
注册都是InstancePerDependency
(以前称为FactoryScope
),因此此语句适用于您的场景。结果,您陷入了创建 M 和 VM 实例的无限循环。如果您希望注入的
VM
属性采用您解析的M
的相同实例,则应该更改M< 的生命周期/code> 为
InstancePerDependency
之外的其他内容(例如SingleInstance
)。如下所示:注意:我还使用更新的 PropertiesAutowired(true) 扩展方法。您可以使用它来代替重现中的 OnActivated 代码。
如果您不希望每个应用有一个
M
实例,您可以设置一个LifetimeScope
并使用InstancePerLifetimeScope
。The Autofac documentation for circular dependencies states:
Both your
M
andVM
registrations areInstancePerDependency
(previously known asFactoryScope
) so this statement applies to your scenario. As a result, you get in an endless loop of creating M and VM instances.If you want the property injected
VM
to take the same instance ofM
that you resolve, you should change the lifetime ofM
to something other thanInstancePerDependency
(e.g.SingleInstance
). This is shown below:Note: I'm also using the more recent PropertiesAutowired(true) extension method. You can use this in place of the OnActivated code in your repro.
If you don't want a single instance of
M
per app, you could setup aLifetimeScope
and useInstancePerLifetimeScope
.对于任何对此感兴趣的人来说,这是执行此操作的新方法:
属性/属性依赖项
For anyone interested here is the new way of doing this:
Property/Property Dependencies