2017-08-13 115 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文档中有描述 –