How to register multiple implementations of the same interface in Asp.Net Core?

前端 未结 24 1942
不思量自难忘°
不思量自难忘° 2020-11-22 10:16

I have services that are derived from the same interface.

public interface IService { }
public class ServiceA : IService { }
public class ServiceB : IService         


        
24条回答
  •  刺人心
    刺人心 (楼主)
    2020-11-22 10:44

    I have created a library for this that implements some nice features. Code can be found on GitHub: https://github.com/dazinator/Dazinator.Extensions.DependencyInjection NuGet: https://www.nuget.org/packages/Dazinator.Extensions.DependencyInjection/

    Usage is straightforward:

    1. Add the Dazinator.Extensions.DependencyInjection nuget package to your project.
    2. Add your Named Service registrations.
        var services = new ServiceCollection();
        services.AddNamed(names =>
        {
            names.AddSingleton("A"); // will resolve to a singleton instance of AnimalService
            names.AddSingleton("B"); // will resolve to a singleton instance of BearService (which derives from AnimalService)
            names.AddSingleton("C", new BearService()); will resolve to singleton instance provided yourself.
            names.AddSingleton("D", new DisposableTigerService(), registrationOwnsInstance = true); // will resolve to singleton instance provided yourself, but will be disposed for you (if it implements IDisposable) when this registry is disposed (also a singleton).
    
            names.AddTransient("E"); // new AnimalService() every time..
            names.AddTransient("F"); // new LionService() every time..
    
            names.AddScoped("G");  // scoped AnimalService
            names.AddScoped("H");  scoped DisposableTigerService and as it implements IDisposable, will be disposed of when scope is disposed of.
    
        });
    
    
    

    In the example above, notice that for each named registration, you are also specifying the lifetime or Singleton, Scoped, or Transient.

    You can resolve services in one of two ways, depending on if you are comfortable with having your services take a dependency on this package of not:

    public MyController(Func namedServices)
    {
       AnimalService serviceA = namedServices("A");
       AnimalService serviceB = namedServices("B"); // BearService derives from AnimalService
    }
    

    or

    public MyController(NamedServiceResolver namedServices)
    {
       AnimalService serviceA = namedServices["A"];
       AnimalService serviceB = namedServices["B"]; // instance of BearService returned derives from AnimalService
    }
    
    

    I have specifically designed this library to work well with Microsoft.Extensions.DependencyInjection - for example:

    1. When you register named services, any types that you register can have constructors with parameters - they will be satisfied via DI, in the same way that AddTransient<>, AddScoped<> and AddSingleton<> methods work ordinarily.

    2. For transient and scoped named services, the registry builds an ObjectFactory so that it can activate new instances of the type very quickly when needed. This is much faster than other approaches and is in line with how Microsoft.Extensions.DependencyInjection does things.

提交回复
热议问题