Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use Dependency Injection in C# .NET 6 application to pass in different instances of the same object with same interface?

I am creating an Azure Function App in Visual Studio with C# and .NET 6.

I have a service I created (CosmosDBService) that implements the interface ICosmosDBService:

public class CosmosDbService : ICosmosDbService
{
    private Container? _container = null;

    public CosmosDbService(
        CosmosClient cosmosDbClient,
        string databaseName,
        string containerName)
    {
        _container = cosmosDbClient.GetContainer(databaseName, containerName);
    }

I want to pass two different instances of this service into the Function App. Each service instance would represent a different container.

How would I set this up in Startup:FunctionsApp class using the FunctionsHostBuilder?

like image 714
Mike Lenart Avatar asked Dec 05 '25 17:12

Mike Lenart


2 Answers

Default DI container does not support named such scenarios so you have next options - either create separate interfaces and implementations (and register/resolve them) for each databaseName-containerName pair or create a factory and use it to generate desired CosmosDbService instance:

public interface ICosmosDbServiceFactory
{
    ICosmosDbService Create(string databaseName, string containerName);
}

class CosmosDbServiceFactory : ICosmosDbServiceFactory
{
    private readonly IServiceProvider _serviceProvider;

    public CosmosDbServiceFactory(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public ICosmosDbService Create(string databaseName, string containerName) => new CosmosDbService(
        _serviceProvider.GetRequiredService<CosmosClient>(),
        databaseName,
        containerName
    );
}

Register it with appropriate lifetime and inject it into corresponding class and use it in the constructor to resolve required ICosmosDbService instances.

like image 157
Guru Stron Avatar answered Dec 08 '25 06:12

Guru Stron


You can do this, but I wouldn't recommend it. For instance in your start up if you had the following code:

services.AddSingleton<ICosmosDbService, CosmosDbService>();
services.AddSingleton<ICosmosDbService, OtherCosmosDbService>();

both instances would be registered in the Di container. If you had a class that depends on this interface, the following constructor would result in OtherCosmosDbService being injected:

public class SomeClass {
   private readonly ICosmosDbService _service;
   public SomeClass(ICosmosDbService service){
      _service = service; // This would be OtherCosmosDbService
   }
}

Both would be registered and in this instance, the last one registered "wins". If you wanted to get both then you could change the constructor to this:

public SomeClass(IEnumerable<ICosmosDbService> services){
   // Write logic to handle finding which one you want
}

Honestly, I would go with Guru Stron's suggestion of creating separate interfaces for each container and registering them separately.

like image 27
Nick Cipollina Avatar answered Dec 08 '25 06:12

Nick Cipollina



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!