Asp.net web api NSeviceBus 6-如何使用Autofac将IMessageSession注入.Net Web API控制器?

Asp.net web api NSeviceBus 6-如何使用Autofac将IMessageSession注入.Net Web API控制器?,asp.net-web-api,inversion-of-control,autofac,nservicebus,Asp.net Web Api,Inversion Of Control,Autofac,Nservicebus,我在使用NserviceBus6、Autofac和.NETWebAPI应用程序时遇到了一些鸡和蛋的问题。根据美国国家安全局的文件。当我在Startup.cs中进行端点配置时,我需要给它一个预构建的容器,但是我还需要注册随后创建的端点 Autofac抱怨使用Builder.Update()修改容器已过时。这是可行的,但我想得到一些反馈,如果可能的话,找到更好的方法 var httpConfig = new HttpConfiguration(); var buil

我在使用NserviceBus6、Autofac和.NETWebAPI应用程序时遇到了一些鸡和蛋的问题。根据美国国家安全局的文件。当我在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);
var-httpConfig=new-HttpConfiguration();
var builder=new ContainerBuilder();
RegisterAssemblyModule(Assembly.getExecutionGassembly());
RegisterApiControllers(Assembly.getExecutionGassembly()).PropertiesAutowired();
var container=builder.Build();
httpConfig.DependencyResolver=新的AutoFacWebApidencyResolver(容器);
变量配置=新的端点配置(“..”);
config.sendFailedMessageTo(“错误”);
//......
config.SendOnly();
config.UseContainer(定制=>
{
定制。现有LifetimeScope(容器);
});
var endpointInstance=Endpoint.Start(config).GetAwaiter().GetResult();
//现在需要将IMessageSession注入控制器
var builder=new ContainerBuilder();
RegisterInstance(endpointInstance).As();
//Autofac表示更新已过时,不能修改
//容器建成后!
生成器更新(容器);

您可以在此处使用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();
}
通过使用
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.
var endpointConfig=newendpointconfiguration(“…”);
builder.Register(ctx=>CreateMessageSession(endpointConfig,ctx.Resolve()))
.As()
.SingleInstance();
//使用endpointConfig执行进一步的工作-不会调用lambda
//直到你真正解决了IMessageSession所以闭包是
//像个懒汉。

即使您的需求更复杂,我认为像这样的对象上的lambda和闭包将是您尝试更新构建容器的方法。

为什么首先需要注入IMessageSession?如果您解释了您想要实现的目标,我们可以想出一个替代方案,这样您在构建容器后就不需要更新容器。看起来这段代码与您使用的代码不太一样,因为您在同一范围内有两个名为“config”的变量。@HadiEskandari我需要能够从我的web api控制器发送消息。在NSB 5中,我会添加一个IBus属性,该属性将自动设置为由NSB注入,并使用Bus.Send()。@TravisIllig是的,它只是用来捕获我试图执行的操作,而不是一个完整的配置。我已经在代码中修复了httpConfig。
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.