Search code examples
c#dependency-injectionsimple-injector

Can Simple Injector register multiple instances of same type using different constructor parameters?


I'm investigating using Simple Injector as my dependency injector. I'm tentatively going to use different instances of MemoryCache class as injected dependencies:

public class WorkflowRegistrationService : IWorkflowRegistrationService
{
    public WorkflowRegistrationService( MemoryCache cache ) {}
}

public class MigrationRegistrationService : IMigrationRegistrationService
{
    public MigrationRegistrationService( MemoryCache cache ) {}
}

If I were newing up the classes I'd do something like the following to create different caches for each of these services:

var workflowRegistrationCache = new MemoryCache("workflow");
var migrationRegistrationCache = new MemoryCache("migration");

How might this be done with Simple Injector? Essentially, I need to tell it to use specific instances when injected into specific types.


Solution

  • The easiest way to do this is probably as follows:

    var workflowRegistrationCache = new MemoryCache("workflow");
    
    container.Register<IWorkflowRegistrationService>(
        () => new WorkflowRegistrationService(workflowRegistrationCache));
    
    var migrationRegistrationCache = new MemoryCache("migration");
    
    container.Register<IMigrationRegistrationService>(
        () => new MigrationRegistrationService(
            container.GetInstance<ISomeService>(),
            migrationRegistrationCache));
    

    Another option is to do context bases injection. If you use the code snippet given here, you can do the following registration:

    var workflowRegistrationCache = new MemoryCache("workflow");
    var migrationRegistrationCache = new MemoryCache("migration");
    
    container.RegisterWithContext<MemoryCache>(context =>
    {
       return context.ServiceType == typeof(IWorkflowRegistrationService)
           ? workflowRegistrationCache 
           : migrationRegistrationCache;
    });
    
    container.Register<IWorkflowRegistrationService, WorkflowRegistrationService>();
    container.Register<IMigrationRegistrationService, MigrationRegistrationService>();
    

    This allows you to let the WorkflowRegistrationService and MigrationRegistrationService be auto-wired by the container, allowing other dependencies to be easily injected as well.

    But do note that there's some ambiguity in your design and you might want to address this issue. This Stackoverflow answer goes into more detail about this.