How to inject a IEnumerable<ICustomRepository> in constructor, so I can decide which one to use in the base class?

Viewed 110

I don't no which pattern this is, but I want to accomplish to add an IEnumerable of multiple classes which uses DI also. In my example I want to inject the IEnumerable<ICustomRepository> in the BaseRepository, filled with the Custom2Repository and Custom2Repository classes which have this ICustomRepository interface and uses also injection. Can anybody help me in the right direction?

This is the main class

public class BaseRepository : IBaseRepository
{
    private readonly IProvider _provider;
    private readonly DbContext _dbContext;
    private readonly IEnumerable<ICustomRepository> _customRepositories;
    private string _databaseName;

    public BaseRepository(IProvider provider, DbContext dbContext, **IEnumerable<ICustomRepository> customRepositories**)
    {
        _provider = provider;
        _dbContext = dbContext;
        _customRepositories = customRepositories;
    }

    public async Task ChangeAsync(string id, CancellationToken cancellationToken)
    {
        var tracker = _provider.Get();
        var change = tracker.GetChange(id);
        foreach (var repo in **_customRepositories**)
            if (repo.EntityName == change.EntityName)
            {
                _databaseName = repo.DatabaseName;
                repo.Method1(id, cancellationToken)
            }
        await tracker.SaveChangesAsync(_databaseName, cancellationToken);
    }
    ...
}

This I want to inject the base IEnumerable in the baseRepository

public class Custom1Repository : ICustomRepository
{
    public Custom1Repository(IProvider provider, DbContext dbContext)
    {
        _provider = provider;
        _tracker = tracker.Get();
        _dbContext = dbContext;
    }

    public string EntityName => "EntityOne";
    public string DatabaseName { get; private set; }
    public async Task Method1Async(string id, CancellationToken cancellationToken)
    ...
}

This I want to inject the base IEnumerable in the baseRepository too

public class Custom2Repository : ICustomRepository 
{
    public Custom2Repository(IProvider provider, DbContext dbContext)
    {
        _provider = provider;
        _tracker = tracker.Get();
        _dbContext = dbContext;
    }

    public string EntityName => "EntityTwo";
    public string DatabaseName { get; private set; }
    public async Task Method1Async(string id, CancellationToken cancellationToken)
    ...
}

Thanks for the input. I solved it by removing the ITracker in the Custom1Repository and Custom2Repository classes. I already had this 2 classes registered in the serviceCollection as mentioned below.

2 Answers

You can do it like so:

        serviceCollection
            .AddSingleton<ICustomRepository , Custom1Repository>();
        serviceCollection
            .AddSingleton<ICustomRepository , Custom2Repository>();

Then use it like:

public BaseRepository(IProvider provider, DbContext dbContext, IEnumerable<ICustomRepository> customRepositories)
{
    _provider = provider;
    _dbContext = dbContext;
    _customRepositories = customRepositories;
}

you can't do this. Try inject a CustomRepositoryFactory instead. And with this class you could create ICustomRepository.

Related