【问题标题】:Autofac does not recognize my IServiceCollectionAutofac 无法识别我的 IServiceCollection
【发布时间】:2020-07-14 15:30:53
【问题描述】:

我正在创建一个基于eShopOnContainers 微服务架构的项目

我根据 .NET Core 3+ 对 program.csstartup.cs 做了一些更改

Program.cs

public static IHostBuilder CreateHostBuilder(IConfiguration configuration, string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseServiceProviderFactory(new AutofacServiceProviderFactory())

Startup.cs:

// ConfigureContainer is where you can register things directly
// with Autofac. This runs after ConfigureServices so the things
// here will override registrations made in ConfigureServices.
// Don't build the container; that gets done for you by the factory.
public void ConfigureContainer(ContainerBuilder builder)
{
     //configure autofac
     // Register your own things directly with Autofac, like:
     builder.RegisterModule(new MediatorModule());
     builder.RegisterModule(new ApplicationModule(Configuration));

 }

现在在Startup.csAddCustomIntegrations() 方法中注册IRabbitMQPersistentConnection,它返回DefaultRabbitMQPersistentConnection 并配置IConnectionFactory

public static IServiceCollection AddCustomIntegrations(this IServiceCollection services, IConfiguration configuration)
    {
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        services.AddTransient<IIdentityService, IdentityService>();
        services.AddTransient<IVehicleManagementIntegrationEventService, VehicleManagementIntegrationEventService>();

        services.AddTransient<Func<DbConnection, IIntegrationEventLogService>>(
            sp => (DbConnection c) => new IntegrationEventLogService(c));


        services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
        {
             var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();


             var factory = new ConnectionFactory()
             {
                 HostName = configuration["EventBusConnection"],
                 DispatchConsumersAsync = true
             };

             if (!string.IsNullOrEmpty(configuration["EventBusUserName"]))
             {
                 factory.UserName = configuration["EventBusUserName"];
             }

             if (!string.IsNullOrEmpty(configuration["EventBusPassword"]))
             {
                 factory.Password = configuration["EventBusPassword"];
             }

             var retryCount = 5;
             if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"]))
             {
                 retryCount = int.Parse(configuration["EventBusRetryCount"]);
             }

             return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount);
        });
        
        return services;
    }
public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration)
{
     var subscriptionClientName = configuration["SubscriptionClientName"];

      services.AddSingleton<IEventBus, EventBusRabbitMQ>(sp =>
      {
          var rabbitMQPersistentConnection = sp.GetRequiredService<IRabbitMQPersistentConnection>();
          var iLifetimeScope = sp.GetRequiredService<ILifetimeScope>();
          var logger = sp.GetRequiredService<ILogger<EventBusRabbitMQ>>();
          var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();

           var retryCount = 5;
            if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"]))
            {
                 retryCount = int.Parse(configuration["EventBusRetryCount"]);
            }

            return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount);
         });

     services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();

      return services;
}

当我运行应用程序时,我收到以下错误:

Autofac.Core.DependencyResolutionException: An exception was thrown while activating IFMS.GMT.BuildingBlocks.Infrastructure.Events.EventBusRabbitMQ.EventBusRabbitMQ -> IFMS.GMT.BuildingBlocks.Infrastructure.Events.EventBusRabbitMQ.DefaultRabbitMQPersistentConnection.
 ---> Autofac.Core.DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'IFMS.GMT.BuildingBlocks.Infrastructure.Events.EventBusRabbitMQ.DefaultRabbitMQPersistentConnection' can be invoked with the available services and parameters:
Cannot resolve parameter 'RabbitMQ.Client.IConnectionFactory connectionFactory' of constructor 'Void .ctor(RabbitMQ.Client.IConnectionFactory, Microsoft.Extensions.Logging.ILogger`1[IFMS.GMT.BuildingBlocks.Infrastructure.Events.EventBusRabbitMQ.DefaultRabbitMQPersistentConnection], Int32)'.

Autofac 似乎找不到使用AddCustomIntegrations() 注册的服务

【问题讨论】:

  • 建议在 AddCustomIntegrations 的开头和 AddSingleton 的工厂 lambda 中放置断点,以确保这实际上是被引导的。您还可以向您的类构造器展示您在哪里注入 IRabbitMQPersistentConnection 依赖项吗?
  • @StuartLC IRabbitMQPersistentConnection 仅在AddCustomIntegrations 中被引用:services.AddSingleton&lt;IRabbitMQPersistentConnection&gt;(sp =&gt; 是否应该在其他地方注册它??
  • 我的意思是需要IRabbitMQPersistentConnection 依赖的实际类。顺便说一句,您似乎在混合引导技术 - 因为您已经在使用 AutoFac 模块,为什么不将您在 AddCustomIntegrations 中的内容移动到另一个 IntegrationsModule 并使用与 MediatorModule 等建立的相同模式。跨度>
  • @StuartLC 谢谢我采纳了你的建议并将所有内容移至IntegrationsModule 并使用了 AutoFac。它有效
  • @StuartLC 你能检查一下我的答案吗??

标签: c# asp.net-core-3.1


【解决方案1】:

我将所有代码从 AddCustomIntegrations()AddEventBus() 移动到一个单独的 Module 类,该类继承自 Autofac.Module 类并且它有效

protected override void Load(ContainerBuilder builder)
{
    builder.RegisterType<InMemoryEventBusSubscriptionsManager>()
               .As<IEventBusSubscriptionsManager>()
               .InstancePerLifetimeScope();


    builder.Register<IRabbitMQPersistentConnection>(fff => 
    {
        var logger = fff.Resolve<ILogger<DefaultRabbitMQPersistentConnection>>();
        
        var factory = new ConnectionFactory()
        {
            HostName = Configuration["EventBusConnection"],
            DispatchConsumersAsync = true
        };

        if (!string.IsNullOrEmpty(Configuration["EventBusUserName"]))
        {
            factory.UserName = Configuration["EventBusUserName"];
        }

        if (!string.IsNullOrEmpty(Configuration["EventBusPassword"]))
        {
            factory.Password = Configuration["EventBusPassword"];
        }

        var retryCount = 5;
        if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"]))
        {
            retryCount = int.Parse(Configuration["EventBusRetryCount"]);
        }

            return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount);

     });
}

【讨论】:

  • 是的,就是这样 - 模块是 AF 中引导的标准方式,允许干净地拆分不同的关注点。不过,您的 lambda 参数 fff 更常被命名为“上下文”...
猜你喜欢
  • 2012-12-26
  • 2022-01-23
  • 2011-08-22
  • 2010-10-17
  • 1970-01-01
  • 1970-01-01
  • 2014-08-07
  • 2017-05-08
  • 2017-01-19
相关资源
最近更新 更多