【问题标题】:.net core dependency injection, inject with parameters.net核心依赖注入,带参数注入
【发布时间】:2019-02-16 17:48:22
【问题描述】:

这是 .NET Core 2.0 控制台应用程序,使用 DI 如何将参数传递给构造函数。

RabbitMQPersistentConnection 类需要在构造函数上传递参数

RabbitMQPersistentConnection(ILogger logger, IConnectionFactory connectionFactory, IEmailService emailService);

我的实例

var _emailService = sp.GetRequiredService();

当我将它初始化为服务时不会这样工作

Program.cs

public static class Program
{
    public static async Task Main(string[] args)
    {
        // get App settings
        var builder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
        IConfigurationRoot configuration = builder.Build();           


        //Initilize Service Collection
        #region Initilize Service Collection
        var serviceProvider = new ServiceCollection()
              .AddLogging()
              .AddEntityFrameworkSqlServer().AddDbContext<EmailDBContext>(option => option.UseSqlServer(configuration.GetConnectionString("connection_string")))
              .AddSingleton<IEmailConfiguration>(configuration.GetSection("EmailConfiguration").Get<EmailConfiguration>())                    
              .AddScoped<ISMTPService, SMTPService>()
              .AddScoped<IEmailService, EmailService>()
              .BuildServiceProvider();
        #endregion

       .ConfigureServices((hostContext, services) =>
           {
               services.AddLogging();
               services.AddHostedService<LifetimeEventsHostedService>();
               services.AddHostedService<TimedHostedService>();
               services.AddEntityFrameworkSqlServer();                   
               services.AddScoped<IRabbitMQPersistentConnection, RabbitMQPersistentConnection>(sp =>
               {
                   var logger = sp.GetRequiredService<ILogger<RabbitMQPersistentConnection>>();
                   var _emailService = sp.GetRequiredService<IEmailService>(); // Not Working. :(

                   var _rabbitMQConfiguration = configuration.GetSection("RabbitMQConfiguration").Get<RabbitMQConfiguration>();

                   var factory = new ConnectionFactory()
                   {
                       HostName = _rabbitMQConfiguration.EventBusConnection
                   };

                   if (!string.IsNullOrEmpty(_rabbitMQConfiguration.EventBusUserName))
                   {
                       factory.UserName = _rabbitMQConfiguration.EventBusUserName;
                   }

                   if (!string.IsNullOrEmpty(_rabbitMQConfiguration.EventBusPassword))
                   {
                       factory.Password = _rabbitMQConfiguration.EventBusPassword;
                   }

                   return new RabbitMQPersistentConnection(logger, factory, _emailService);
               });

           })
          .Build();

        await host.RunAsync();
    }
}

RabbitMQPersistentConnection.cs

public class RabbitMQPersistentConnection : IRabbitMQPersistentConnection
{
    private readonly IConnectionFactory _connectionFactory;
    EventBusRabbitMQ _eventBusRabbitMQ;
    IConnection _connection;
    IEmailService _emailService;
    private readonly ILogger _logger;
    bool _disposed;     

    public RabbitMQPersistentConnection(ILogger<RabbitMQPersistentConnection> logger, IConnectionFactory connectionFactory, IEmailService emailService)
    {
        _connectionFactory = connectionFactory ?? throw new ArgumentNullException(nameof(connectionFactory));
        _emailService = emailService;
        _logger = logger;          
    }
}

【问题讨论】:

    标签: c# asp.net-core dependency-injection .net-core console-application


    【解决方案1】:

    您正在“初始化服务集合”区域中创建自己的IServiceProvider,这是IServiceProvider 的一个不同实例,与您在此处使用的实例不同:

    var _emailService = sp.GetRequiredService<IEmailService>();
    

    您在您所在地区的注册只是被丢弃了。为了解决这个问题,您可以将这些注册信息拉入您的 HostBuilder.ConfigureServices 回调函数中:

    .ConfigureServices((hostContext, services) =>
    {
        services.AddLogging();
        services.AddHostedService<LifetimeEventsHostedService>();
        services.AddHostedService<TimedHostedService>();
        services.AddEntityFrameworkSqlServer();
        services.AddDbContext<EmailDBContext>(option => option.UseSqlServer(configuration.GetConnectionString("connection_string")));
        services.AddSingleton<IEmailConfiguration>(configuration.GetSection("EmailConfiguration").Get<EmailConfiguration>());
        services.AddScoped<ISMTPService, SMTPService>();
        services.AddScoped<IEmailService, EmailService>();
        services.AddScoped<IRabbitMQPersistentConnection, RabbitMQPersistentConnection>(sp =>
        {
            var logger = sp.GetRequiredService<ILogger<RabbitMQPersistentConnection>>();
            var _emailService = sp.GetRequiredService<IEmailService>();                      
            var _rabbitMQConfiguration = configuration.GetSection("RabbitMQConfiguration").Get<RabbitMQConfiguration>();
    
            var factory = new ConnectionFactory()
            {
                HostName = _rabbitMQConfiguration.EventBusConnection
            };
    
            if (!string.IsNullOrEmpty(_rabbitMQConfiguration.EventBusUserName))
            {
                factory.UserName = _rabbitMQConfiguration.EventBusUserName;
            }
    
            if (!string.IsNullOrEmpty(_rabbitMQConfiguration.EventBusPassword))
            {
                factory.Password = _rabbitMQConfiguration.EventBusPassword;
            }
    
            return new RabbitMQPersistentConnection(logger, factory, _emailService);
        });
    })
    

    【讨论】:

    • 我不知道之前发生了什么。当我将 EmailService 更改为 IEmailService 后,您的答案有效
    • 在您对我的回答所做的编辑中,您添加了IEmailConfiguration 的注册。如果您的 IEmailService 将其作为构造函数参数,那肯定可以解释为什么它在此之前不起作用。
    猜你喜欢
    • 2018-12-14
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-03
    相关资源
    最近更新 更多