2017-10-13 20 views
0

두 가지 시스템, 하나는 게시 메시지 용이고 다른 하나는 시스템 용입니다. 둘 다 Masstransit (RabbitMQ 사용)을 사용하며 ASP.Net 웹 API 2와 OWIN (및 IoC 컨테이너로 Autofac)을 사용하여 구현됩니다. 내 소비자가 종속성이없는 경우 모두 작동합니다 (). 소비자에게 dependenciy를 주입하면 Consume 메서드가 실행되지 않습니다. (초기화 중에 오류가 발생하지 않음).IConsumer를 등록하십시오 Autofac를 사용하여 Masstransit에 의존성이있는 <T>을 등록하십시오.

이 관련 제작사 코드 :

//Startup.cs 
public class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     HttpConfiguration config = new HttpConfiguration(); 

     IContainer container = null; 
     var builder = new ContainerBuilder(); 

     builder.Register(context => 
     { 
      var busControl = Bus.Factory.CreateUsingRabbitMq(cfg => 
      { 
       IRabbitMqHost rabbitMqHost = cfg.Host(new Uri(ConfigurationManager.AppSettings["RabbitMQHost"]), settings => 
       { 
        settings.Username(ConfigurationManager.AppSettings["RabbitMQUser"]); 
        settings.Password(ConfigurationManager.AppSettings["RabbitMQPassword"]); 
       }); 
      }); 

      return busControl; 
     }) 
     .As<IBusControl>() 
     .As<IBus>() 
     .SingleInstance(); 

     // Register Web API controllers 
     builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); 

     // Resolve dependencies 
     container = builder.Build(); 
     config.DependencyResolver = AutofacWebApiDependencyResolver(container); 

     WebApiConfig.Register(config); 
     SwaggerConfig.Register(config); 
     app.UseCors(CorsOptions.AllowAll); 

     // Register the Autofac middleware FIRST. 
     app.UseAutofacMiddleware(container); 
     app.UseWebApi(config); 

     // Starts MassTransit Service bus, and registers stopping of bus on app dispose 
     var bus = container.Resolve<IBusControl>(); 
     var busHandle = bus.StartAsync(); 
     var properties = new AppProperties(app.Properties); 
     if (properties.OnAppDisposing != CancellationToken.None) 
     { 
      properties.OnAppDisposing.Register(() => busHandle.Result.StopAsync(TimeSpan.FromSeconds(30))); 
     } 
    } 
} 

// Controller 
public IHttpActionResult Post() 
{ 
    _bus.Publish<IFooMessage>(new 
    { 
     Foo = "Foo" 
    }); 

    return Ok(); 
} 

그리고 이것은 관련 소비자 코드 :

// Startup.cs 
public class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     HttpConfiguration config = new HttpConfiguration(); 

     IContainer container = null; 
     var builder = new ContainerBuilder(); 

     builder.RegisterType<FooService>().As<IFooService>().InstancePerRequest(); 
     builder.RegisterModule<BusModule>(); 
     builder.RegisterModule<ConsumersModule>(); 

     // Register Web API controllers 
     builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); 

     // Resolve dependencies 
     container = builder.Build(); 
     config.DependencyResolver = new AutofacWebApiDependencyResolver(container); 

     WebApiConfig.Register(config); 
     SwaggerConfig.Register(config); 
     app.UseCors(CorsOptions.AllowAll); 

     // Register the Autofac middleware FIRST. 
     app.UseAutofacMiddleware(container); 
     app.UseWebApi(config); 

     // Starts MassTransit Service bus, and registers stopping of bus on app dispose 
     var bus = container.Resolve<IBusControl>(); 
     var busHandle = bus.StartAsync(); 
     var properties = new AppProperties(app.Properties); 
     if (properties.OnAppDisposing != CancellationToken.None) 
     { 
      properties.OnAppDisposing.Register(() => busHandle.Result.StopAsync(TimeSpan.FromSeconds(30))); 
     } 
    } 
} 

// BusModule.cs 
public class BusModule : Module 
{ 
    protected override void Load(ContainerBuilder builder) 
    { 
     builder.Register(context => 
     { 
      var busControl = Bus.Factory.CreateUsingRabbitMq(cfg => 
      { 
       IRabbitMqHost rabbitMqHost = cfg.Host(new Uri(ConfigurationManager.AppSettings["RabbitMQHost"]), settings => 
       { 
        settings.Username(ConfigurationManager.AppSettings["RabbitMQUser"]); 
        settings.Password(ConfigurationManager.AppSettings["RabbitMQPassword"]); 
       }); 
       cfg.ReceiveEndpoint(rabbitMqHost, "IP.AgilePoint.queue", ec => 
       { 
        ec.LoadFrom(context); 
       }); 
      }); 

      return busControl; 
     }) 
     .SingleInstance() 
     .As<IBusControl>() 
     .As<IBus>(); 
    } 
} 

// ConsumerModule.cs 
public class ConsumersModule : Module 
{ 
    protected override void Load(ContainerBuilder builder) 
    { 
     builder.RegisterType<FooConsumer>(); 
    } 
} 

// FooConsumer.cs 
public class FooConsumer : IConsumer<IFooMessage> 
{ 
    private IFooService _service; 

    public FooConsumer(IFooService service) 
    { 
     _service = service; 
    } 

    public Task Consume(ConsumeContext<IFooMessage> context) 
    { 
     IFooMessage @event = context.Message; 

     _service.DoStuff(@event.Foo); 

     return Task.FromResult(context.Message); 
    } 
} 

내 FooConsumer을 참고 종속성 (생성자)가 IFooService합니다. 나는 Masstransit documentation을 따라 왔지만 제대로 작동하지 않습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?

프레임 워크 버전 :

  • 닷넷 프레임 워크 4.6.1
  • Autofac : 3.5.2
  • Masstransit : 3.5.7

업데이트 :

코드 찾을 수 있습니다 in this Github repository

답변

0

마지막으로 내가 잘못하고 있었는지 발견했다. 어떤 이유로 RabbitMQ Management에서 대기열을 볼 수 없었습니다. 내가 오류 큐를 볼 수 있었다 때, 나는 다음과 같은 오류 드주의 :이 방법으로 내 IFooService 등록 된

RabbitMQ Error

다음 InstancePerRequest() 오류를 일으키는

builder.RegisterType<FooService>().As<IFooService>().InstancePerRequest(); 

. builder.RegisterType<FooService>().As<IFooService>()으로 서비스를 등록하면 모든 것이 잘 동작합니다. 내 버스 인스턴스가 싱글 톤 (SingleIsntace()으로 등록)으로 작동하고 있기 때문이라고 생각합니다. 웹 API 프로젝트를 사용하여 버스/소비자를 호스팅한다는 사실은 나 혼란을 야기했다.

어쨌든 @Chris Patterson과 @Alexey Zimarev 덕분에 올바른 방향으로 구현할 수있었습니다 (소비자 등록을 위해 MT 확장 사용).

+1

요청 별 등록은 Autofac이 요청 범위를 관리하는 경우에만 적용되며 WebAPI 통합 플러그인에서 수행됩니다. MassTransit은 그것을 사용하지 않습니다. 기본 등록은 * singleton *이 아니며 종속성 당입니다. 이것은 올바른 범위입니다. MassTransit은 각 메시지에 대해 소비자를 인스턴스화합니다. –

3

필자는 Autofac과 관련된 설명서를 보길 권합니다. 확장 라이브러리를 통해 완벽하게 지원되는 컨테이너입니다.

http://masstransit-project.com/MassTransit/usage/containers/autofac.html

패키지 : https://www.nuget.org/packages/masstransit.autofac

+0

내가 볼 수없는 어리석은 실수를하지 않는 한 이것이 내가하는 일이라고 생각한다. 내 FooConsumer 생성자가 호출되지 않는다 –

+0

MT가 컨텍스트에서로드하도록 요청하지만 Autofac에 소비자를 등록하는 코드를 확인하십시오.등록되지 않았다면 어떻게 해결할 것이라고 기대하십니까? –