How can I pass a runtime parameter as part of the dependency resolution?

前端 未结 5 1829
不知归路
不知归路 2021-01-30 10:28

I need to be able to pass a connection string into some of my service implementations. I am doing this in the constructor. The connection string is configurable by user will be

5条回答
  •  日久生厌
    2021-01-30 11:20

    To pass runtime parameter not known at the start of the application you have to use the factory pattern. You have two options here

    1. factory method

       services.AddTransient>((provider) => 
       {
           return new Func( 
               (connectionString) => new NestedService(connectionString)
           );
       });
      

      and inject the factory method in your service instead of INestedService.

       public class RootService : IRootService
       {
           public INestedService NestedService { get; set; }
      
           public RootService(Func nestedServiceFactory)
           {
               NestedService = nestedServiceFactory("ConnectionStringHere");
           }
      
           public void DoSomething()
           {
               // implement
           }
       }
      

      or resolve it per call

       public class RootService : IRootService
       {
           public Func NestedServiceFactory { get; set; }
      
           public RootService(Func nestedServiceFactory)
           {
               NestedServiceFactory = nestedServiceFactory;
           }
      
           public void DoSomething(string connectionString)
           {
               var nestedService = nestedServiceFactory(connectionString);
      
               // implement
           }
       }
      
    2. factory class

       public class RootServiceFactory : IRootServiceFactory 
       {
           // in case you need other dependencies, that can be resolved by DI
           private readonly IServiceCollection services;
      
           public RootServiceCollection(IServiceCollection services)
           {
               this.services = services;
           }
      
           public CreateInstance(string connectionString) 
           {
               // instantiate service that needs runtime parameter
               var nestedService = new NestedService(connectionString);
      
               // resolve another service that doesn't need runtime parameter
               var otherDependency = services.GetService()
      
               // pass both into the RootService constructor and return it
               return new RootService(otherDependency, nestedDependency);
           }
       }
      

      and inject IRootServiceFactory instead of your IRootService.

       IRootService rootService = rootServiceFactory.CreateInstance(connectionString);
      

提交回复
热议问题