2017-08-13 112 views
0

上下文:ASP.NET Core App(1.1)。Autofac&MassTransit - 註冊用戶ObjectDisposedException

我試圖解決我已經註冊的IRepository,當我需要一個消費者實例時,但它看起來像我收到ObjectDisposedException。

BusFactoryMethod

我創造了我的呼喚了ContainerBuilder.Build()方法自動激活總線工廠方法。

public IServiceProvider ConfigureServices(IServiceCollection services) 
{ 
    var containerBuilder = new ContainerBuilder(); 
    containerBuilder.RegisterType<EventTypeResolver>().As<IEventTypeResolver>(); 
    containerBuilder.RegisterType<Repository>().As<IRepository>(); 
    containerBuilder.Register(c => EventStoreConnectionFactory.Create()) 
          .As<IEventStoreConnection>(); 
    containerBuilder.Register(BusFactoryMethod).AsSelf().SingleInstance().AutoActivate(); 
    containerBuilder.Populate(services); 
    return new AutofacServiceProvider(containerBuilder.Build()); 
} 

BusFactoryMethod看起來是這樣的:

private IBusControl BusFactoryMethod(IComponentContext componentContext) 
{ 
    var busControl = BusConfigurator.Instance.ConfigureBus((cfg, host) => 
      { 
       cfg.ReceiveEndpoint(host, RabbitMQConstants.UserManagementQueue, e => 
       { 
        e.Consumer(() => new CreateUserCommandConsumer(componentContext.Resolve<IRepository>())); 
       }); 
      }); 
    busControl.Start(); 
    return busControl; 
} 
+1

您註冊你的'IRepository'爲短暫的依賴,但你的' IBusControl'是個奇怪的東西,取決於你從哪裏解決'IBusControl',即如果你在請求期間解決它的某個地方,它由作用域容器解決,但是因爲它的單例它g當IRepository由作用域容器解析並放置在請求結束時,但是'IBusControl'不會因爲它的單例而被丟棄 – Tseng

+0

因此,在應用程序啓動期間,您將不得不解決'IBusControl'配置'方法,或更改'IRepository'和'IBusControl'作用域生命週期(可能不可能,因爲您想收聽事件和消息) – Tseng

+0

嗯。是的,就像我註冊BusFactoryMethod和AutoActivate一樣,它會在我構建容器時被調用。但是消費者/存儲庫僅用於請求生存期 –

回答

0

所以,我發現了一個包MassTransit.AutofacIntegration它已經具備了RegisterConsumers方法。

然後我使用Autofac的RegisterGeneric方法來獲得每條消息的生命週期。

containerBuilder.RegisterGeneric(typeof(AutofacConsumerFactory<>)) 
          .WithParameter(new NamedParameter("name", "message")) 
          .As(typeof(IConsumerFactory<>)) 
          .InstancePerLifetimeScope(); 

,結束了與以下Module

public class DefaultModule : Autofac.Module 
     { 
      protected override void Load(ContainerBuilder containerBuilder) 
      { 
       containerBuilder.Register(c => new EventTypeResolver(typeof(DefaultModule).GetTypeInfo().Assembly)).As<IEventTypeResolver>(); 
       containerBuilder.Register(c => EventStoreConnectionFactory.Create()) 
           .As<IEventStoreConnection>(); 
       containerBuilder.RegisterType<Repository>().As<IRepository>(); 
       containerBuilder.RegisterConsumers(typeof(DefaultModule).GetTypeInfo().Assembly).AsSelf().AsImplementedInterfaces(); 
       containerBuilder.RegisterGeneric(typeof(AutofacConsumerFactory<>)) 
          .WithParameter(new NamedParameter("name", "message")) 
          .As(typeof(IConsumerFactory<>)) 
          .InstancePerLifetimeScope(); 
       containerBuilder.Register((c) => 
       { 
        var busControl = BusConfigurator.Instance.ConfigureBus((cfg, host) => 
        { 
         ConfigureEndPoints(cfg, host, c); 
        }); 
        busControl.Start(); 
        return busControl; 
       }).SingleInstance().AutoActivate(); 
      } 

      private void ConfigureEndPoints(IRabbitMqBusFactoryConfigurator cfg, IRabbitMqHost host, IComponentContext context) 
      { 
       cfg.ReceiveEndpoint(host, RabbitMQConstants.UserManagementQueue, e => 
       { 
        e.Consumer(context.Resolve<IConsumerFactory<CreateUserCommandConsumer>>()); 
       }); 
      } 
     } 

ConfigureServices方法現在看起來像這樣:

public IServiceProvider ConfigureServices(IServiceCollection services) 
     { 
      var containerBuilder = new ContainerBuilder(); 
      containerBuilder.RegisterModule<DefaultModule>(); 
      containerBuilder.Populate(services); 
      return new AutofacServiceProvider(containerBuilder.Build()); 
     } 
+1

您可能會感到驚訝,但Autofac適配器在http://masstransit-project.com/MassTransit/usage/containers/autofac.html文檔中有描述 –