我使用NServiceBus 6,Autofac和.NET web api应用程序遇到了鸡蛋和鸡蛋的问题。根据NSB文件,NSB 6 does not automatically inject IMessageSession into a controller。当我在Startup.cs中进行端点配置时,我需要给它一个预先构建的容器,但是我还需要注册后来创建的端点。
Autofac抱怨使用Builder.Update()
修改容器已经过时了。它有效,但我希望得到一些反馈,如果可能的话,更好的方法。
var httpConfig = new HttpConfiguration();
var builder = new ContainerBuilder();
builder.RegisterAssemblyModules(Assembly.GetExecutingAssembly());
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();
var container = builder.Build();
httpConfig.DependencyResolver = new AutofacWebApiDependencyResolver(container);
var config = new EndpointConfiguration("....");
config.SendFailedMessagesTo("Error");
//......
config.SendOnly();
config.UseContainer<AutofacBuilder>( customizations =>
{
customizations.ExistingLifetimeScope(container);
});
var endpointInstance = Endpoint.Start(config).GetAwaiter().GetResult();
// This is now needed to get IMessageSession injected into the controller
var builder = new ContainerBuilder();
builder.RegisterInstance(endpointInstance).As<IMessageSession>();
// Autofac says Update is OBSOLETE and not to modify the
// container after it is built!
builder.Update(container);
答案 0 :(得分:2)
您可以在这里使用lambda注册。
首先,假设您有一个静态方法来创建端点。如果是这样,它将更容易显示示例。它看起来像这样:
public static IMessageSession CreateMessageSession(ILifetimeScope container)
{
var config = new EndpointConfiguration("....");
config.SendFailedMessagesTo("Error");
//......
config.SendOnly();
config.UseContainer<AutofacBuilder>( customizations =>
{
customizations.ExistingLifetimeScope(container);
});
return Endpoint.Start(config).GetAwaiter().GetResult();
}
注意我切换到使用ILifetimeScope
而不是容器。
现在你可以这样做:
builder.Register(ctx => CreateMessageSession(ctx.Resolve<ILifetimeScope>()))
.As<IMessageSession>()
.SingleInstance();
通过使用SingleInstance
,在lambda中解析的生命周期范围实际上将是根容器。事情会根据需要排列。
我认识到你可能需要/希望其他地方有EndpointConfiguration
个对象。你仍然可以使用lambdas但是在对象上注册一个闭包。更改静态方法以接受端点配置和...
var endpointConfig = new EndpointConfiguration("....");
builder.Register(ctx => CreateMessageSession(endpointConfig, ctx.Resolve<ILifetimeScope>()))
.As<IMessageSession>()
.SingleInstance();
// Do further work with endpointConfig - lambda won't get called
// until you actually resolve IMessageSession so the closure is
// like a lazy bind.
即使您的要求更复杂,我认为对这样的对象进行lambdas和闭包将是您尝试更新构建容器的方法。