2

NServiceBus 6, Autofac 및 .NET 웹 API 응용 프로그램을 사용하여 닭고기 및 달걀 문제가 발생했습니다. NSB 문서에 따르면, NSB 6 does not automatically inject IMessageSession into a controller. Startup.cs에서 끝점 구성을 수행 할 때 미리 작성된 컨테이너를 제공해야하지만 이후에 만든 끝점을 등록해야합니다.NSeviceBus 6 - .Net 웹 API 컨트롤러에 Autofac을 사용하여 IMessageSession을 주입하는 방법?

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

왜 IMessageSession을 삽입해야합니까? 달성하고자하는 것을 설명하면 대안을 제안 할 수 있으므로 일단 작성된 컨테이너를 업데이트 할 필요가 없습니다. –

+0

동일한 범위에서 "config"라는 두 개의 변수가 있기 때문에이 코드가 사용중인 코드처럼 보이지 않습니다. –

+0

@HadiEskandari 내 웹 API 컨트롤러에서 메시지를 보낼 수 있어야합니다. NSB 5에서는 NSB가 주입하도록 Bususend 속성을 자동으로 추가하고 Bus.Send()를 사용했습니다. –

답변

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를 사용하도록 전환.

지금 당신은이 작업을 수행 할 수 있습니다

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

효과적으로 루트 컨테이너 될 것 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. 

심지어, 나는이 같은 객체를 통해 람다 및 폐쇄가 업데이트하려고 주위로 길을 가고 있다고 생각 ...뿐만 아니라 엔드 포인트 구성에 적용하려면 정적 방법을 변경하고 건설 된 컨테이너.

관련 문제