2

NServiceBus 6、Autofac、および.NET Webアプリケーションを使用して、チキンと卵の問題が発生しています。 NSBの文書、NSB 6 does not automatically inject IMessageSession into a controllerによると、 Startup.csでエンドポイント構成を行うときに、あらかじめ作成されたコンテナを与える必要がありますが、その後に作成されたエンドポイントも登録する必要があります。NSeviceBus 6 - .Net Web APIコントローラにAutofacを使用してIMessageSessionを挿入する方法

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

なぜIMessageSessionを最初に挿入する必要がありますか?あなたが達成したいことを説明するならば、我々は一度構築したコンテナを更新する必要はないので、代替案を思いつくことができます。 –

+0

同じスコープ内に "config"という名前の2つの変数があるので、このコードは使い慣れたものではありません。 –

+0

@ HadiEskandari私はWeb APIコントローラからメッセージを送信できる必要があります。 NSB 5では、NSBによって注入されるように自動的に設定され、Bus.Send()を使用するIBusプロパティを追加しました。 –

答えて

1

ここではラムダ登録を利用できます。

まず、エンドポイントの作成を行う静的メソッドがあるとします。もしそうなら、例を示すのが簡単になります。

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を使用するように切り替えました。ラムダで解決寿命の範囲が効果的にルートコンテナになりますSingleInstanceを使用することにより

builder.Register(ctx => CreateMessageSession(ctx.Resolve<ILifetimeScope>())) 
     .As<IMessageSession>() 
     .SingleInstance(); 

今、あなたはこれを行うことができます。物事は必要に応じて並べられます。

他の場所にあるEndpointConfigurationオブジェクトが必要な場合があります。ラムダを使用することはできますが、オブジェクトにクロージャを登録することはできます。要件が複雑であっても、私はこのようなオブジェクトに対するラムダとクロージャを更新しようと周りにあなたの方法になるだろうと思います

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. 
だけでなくエンドポイントの設定で撮影する静的メソッドを変更し、...造られたコンテナ。

関連する問題