Home > Net >  Passing constructor parameters to service when creating it with ServiceProvider
Passing constructor parameters to service when creating it with ServiceProvider

Time:07-25

I have an ASP .Net 6 Web API. In it, I have a Singleton service which requires the use of a Transient service. So I inject IServiceProvider into the Singleton service, and then get an instance of the Transient service as follows:

using (var serviceScope = _serviceProvider.CreateScope())
{
    using (var service = (MyTransientService)serviceScope.ServiceProvider.GetRequiredService<IMyTransientService>())
    {
        // Use transient service
    }
}

Now, I'd like to add some constructor arguments to my Transient service. How would I be able to provide these parameters when getting the service (as in the code above)?

I've searched the internet, but all examples I found show how to pass parameters when registering the service in Startup.cs (in the ConfigureServices() method), when knowing the values of the parameters upfront.

Any pointers would be greatly appreciated. Thanks.

CodePudding user response:

This is not how Dependency Injection is used. If you need a "custom" MyTransientService, create a new Instance.

using (var service = new MyTransientService(/*Arguments*/))
{
    // Use service
}

CodePudding user response:

The .NET Core built-in IoC does not offer this out-of-the-box. One option is to move the parameters from the constructor to the methods.

If you do not want to move the parameters to the methods, you can create and register a factory instead of the service. This factory can receive parameters in its Create method and instantiate the service:

public interface IServiceFactory
{
  IService Create(int i);
}

public class ServiceFactory : IServiceFactory
{
  public IService Create(int i)
  {
    return new Service(i);
  }
}

services.AddSingleton<IServiceFactory, ServiceFactory>();

public class ServiceClient
{
  private readonly IServiceFactory _factory;

  public ServiceClient(IServiceFactory factory) 
  {
    _factory = factory;
  }

  public void DoSomething()
  {
    for (var i = 0; i < 3; i  )
    {
      var svc = _factory.Create(i);
      // ...
    }
  }
}

Though the factory contains a plain new statement, this is not problematic because you can easily register another factory if you want to change the created type.

  • Related