Isanka Thalagala
Isanka Thalagala

Reputation: 1721

.net core dependency injection, inject with parameters

It's .NET Core 2.0 console application, using DI how can I pass parameters to constructor.

RabbitMQPersistentConnection class needs to pass parameter on constructer

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

My instance

var _emailService = sp.GetRequiredService();

not working like this when I initialize it as service

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;          
    }
}

Upvotes: 1

Views: 6005

Answers (1)

Kirk Larkin
Kirk Larkin

Reputation: 93063

You are creating your own IServiceProvider in your "Initilize Service Collection" region, which is a different instance of IServiceProvider to the one that you're using here:

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

The registrations you've made in your region are simply being thrown away. In order to resolve this, you can just pull those registrations into your HostBuilder.ConfigureServices callback function:

.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);
    });
})

Upvotes: 5

Related Questions