Autofac 的运行时注册

20

在与同事讨论Autofac时,出现了关于运行时注册依赖项的问题。例如,在Prism中经常在运行时加载程序集并将其依赖项注册到IoC容器中(通常是Unity)。

如何使用Autofac实现这一点呢?

从Autofac的文档和我在网上找到的信息来看,似乎注册是在应用程序启动时执行的。即使使用“外部”程序集,注册也会在应用程序启动时位于模块中的程序集中进行。那么,在容器在应用程序启动时“构建”之后,我们该怎么做呢?

(请注意,程序集可能需要添加其他组件在应用程序中使用的依赖项,因此嵌套容器可能无法解决此问题。与此主题相关的是:Unity有诸如RegisterIfExists等方法。是否有Autofac相应的方法?)

谢谢!


可能是Autofac,在容器构建后添加服务的重复问题。 - Jim G.
2个回答

32

更新现有的 Autofac 容器: 您可以使用 ContainerBuilder.Update() 方法在运行时更新现有的 Autofac Container。下面是一个示例代码,来自于博客文章 Autofac 2.2 Released

var container = // something already built

var updater = new ContainerBuilder();
updater.RegisterType<A>();
updater.Register(c => new B()).As<IB>();

// Add the registrations to the container
updater.Update(container);

Autofac和Prism的集成: 问题“Autofac中Prism集成的状态是什么?”也可能对您有用。

2021年7月更新 - Autofac已删除了Update方法(虽然我刚刚注意到)。请参见Github上的此问题,以了解在不使用Update的情况下执行您想要的操作的“更好”方法。https://github.com/autofac/Autofac/issues/811


你知道是否可以使用动态加载的程序集中的类型来完成这个操作吗?也就是说,我使用 Assembly.LoadFrom() 方法,然后使用新发现的类型更新容器? - Mark Richman
RegisterType 的其中一个重载接受一个 Type 实例,所以如果你有这个实例,就可以继续了。 - bentayloruk
"Update()"命令只能使用一次。这对于运行时注册来说并不高效。如果可能的话,我需要在“ .Build()”操作后注册新类型... - Oğuzhan Soykan

9

Autofac 4.8.1.0 更新

ContainerBuilder.Update 方法被标记为 Obsolete 并附带以下注释:
容器通常应视为不可变的。在构建/解析之前注册所有依赖项。如果您需要更改容器的内容,则应重新构建容器。该方法可能会在未来的主要版本中移除。


1
为什么在运行时交换实现是不好的?例如,在移动设备上,用户可能会拒绝某些权限,而我可以将实现切换到只忽略它们而不显示通知的实现。为什么这样做很糟糕?另外,也许我需要在运行时注册dbcontexts,因为我需要一个动态连接字符串。 - Taunter exd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接