像异步一样注册 Autofac 模块
Registering Autofac modules acting as if async
我在使用 Autofac 时遇到了一个奇怪的问题。我有一个模块,其 Load
方法如下所示:
builder.RegisterType<Foo>().As<IFoo>();
// ...
AddSomethingToAList(bar);
// ...
其中 AddSomethingToAList
完全按照锡罐上的说明进行操作,将资源添加到静态列表。它用于跟踪一些元数据并保存在模块内,因为该元数据与为依赖注入注册的类型直接相关。
然后我的代码有一个设置方法,如下所示:
var builder = new ContainerBuilder();
builder.RegisterModule(myModule);
foreach(var whatever in previouslyAddedToList)
{
doSomething(whatever);
}
如您所见,我们注册了模块(我希望为该模块调用 Load
),然后我们对加载模块时添加到的列表进行一些操作。
这是奇怪的部分: 在向列表中添加任何内容之前,列表正在处理。这是完全出乎意料的(如果代码是同步的和确定性的)。就好像模块正在被异步处理。如果我只是调用 myModule.Load(builder)
而不是 builder.RegisterModule(myModule)
,那么它将完全按预期工作。
文档中没有任何内容说它是异步的,而且看起来很不合适。我通过在模块的 Load
方法内和处理列表的点放置断点来遵循此行为。
那么 RegisterModule
到底是什么导致了这种异常的执行顺序?为什么?我该如何阻止它?
Autofac 中的所有内容都在内部注册为一系列回调。当您调用 RegisterModule 时,ContainerBuilder 添加一个 lambda 用于调用模块上的 Load。
ContainerBuilder 会保留所有这些回调,直到您调用 Build,它们最终会执行。这就是为什么您看不到立即调用 Load 方法的原因。
没有办法改变这个。
相反,我会强烈建议仅使用模块来注册依赖项并且不会有任何副作用。
我在使用 Autofac 时遇到了一个奇怪的问题。我有一个模块,其 Load
方法如下所示:
builder.RegisterType<Foo>().As<IFoo>();
// ...
AddSomethingToAList(bar);
// ...
其中 AddSomethingToAList
完全按照锡罐上的说明进行操作,将资源添加到静态列表。它用于跟踪一些元数据并保存在模块内,因为该元数据与为依赖注入注册的类型直接相关。
然后我的代码有一个设置方法,如下所示:
var builder = new ContainerBuilder();
builder.RegisterModule(myModule);
foreach(var whatever in previouslyAddedToList)
{
doSomething(whatever);
}
如您所见,我们注册了模块(我希望为该模块调用 Load
),然后我们对加载模块时添加到的列表进行一些操作。
这是奇怪的部分: 在向列表中添加任何内容之前,列表正在处理。这是完全出乎意料的(如果代码是同步的和确定性的)。就好像模块正在被异步处理。如果我只是调用 myModule.Load(builder)
而不是 builder.RegisterModule(myModule)
,那么它将完全按预期工作。
文档中没有任何内容说它是异步的,而且看起来很不合适。我通过在模块的 Load
方法内和处理列表的点放置断点来遵循此行为。
那么 RegisterModule
到底是什么导致了这种异常的执行顺序?为什么?我该如何阻止它?
Autofac 中的所有内容都在内部注册为一系列回调。当您调用 RegisterModule 时,ContainerBuilder 添加一个 lambda 用于调用模块上的 Load。
ContainerBuilder 会保留所有这些回调,直到您调用 Build,它们最终会执行。这就是为什么您看不到立即调用 Load 方法的原因。
没有办法改变这个。
相反,我会强烈建议仅使用模块来注册依赖项并且不会有任何副作用。