在多个构造函数参数中注入具有相同接口的不同实现

时间:2018-07-20 22:52:21

标签: c# asp.net-core dependency-injection .net-core

我的目标是创建一个包含接口的不同实现的对象,并在运行时选择要使用的实现。我正在ASP.NET Core中使用依赖注入。

代码:

public interface IStateRepository : IDbReadRepository<IState> { }

public interface IDbReadRepository<T> : IBaseRepository
{
     IReadOnlyList<T> GetAll();
}

public interface IBaseRepository
{
    IUserContext UserContext { get; set; }
}

namespace MvcOpinionatedTemplate.Repositories.Dapper
{
    public class StateRepository : BaseDbRepository, IStateRepository
    {
        public StateRepository(IUserContext userContext, IDbConnection dbConnection) : base(userContext, dbConnection) { }

        public IReadOnlyList<IState> GetAll()
        {
            return _dbConnection.Query<State>("SELECT * FROM State").ToList();
        }
    }
}

namespace Template.Repositories.Local
{
    public class StateRepository : BaseRepository, IStateRepository
    {
        public StateRepository(IUserContext userContext) : base(userContext) { }

        public IReadOnlyList<IState> GetAll()
        {
            var filePath = Path.Combine(AppContext.BaseDirectory, @"Local\json\states.json");

            return JsonConvert.DeserializeObject<List<State>>(File.ReadAllText(filePath));
        }
}


namespace MvcOpinionatedTemplate.Repositories.Collections
{
    public class StateRepositories
    {
        public IStateRepository Local { get; }

        public IStateRepository SqlServer { get; }

        public StateRepositories(IStateRepository local, IStateRepository sqlServer)
        {
            Local = local;
            SqlServer = sqlServer;
        }
    }
}

我想做的是在Startup.ConfigureServices()中设置的:

services.AddTransient<StateRepositories, XXXXX>

我尝试过:

services.AddTransient<StateRepositories>(s => new StateRepositories(new Repositories.Local.StateRepository(--UserContext--), new Repositories.Dapper.StateRepository(-UserContext--)));

问题在于如何让DI填充UserContext。我已经定义了Startup.ConfigureServices():

services.AddScoped<IUserContext, UserContext>();

DI如何为StateRepositories实现填充UserContext?还是有更好的方法来实现我的目标?

1 个答案:

答案 0 :(得分:2)

您可以分别注册IStateRepository,然后注入IEnumerable<IStateRepository>,从而注入IStateRepository的所有实现。

public interface IStateRepository
{
}

public class LocalRepository : IStateRepository
{
}

public class DapperRepository : IStateRepository
{
}

services.AddTransient<IStateRepository, LocalRepository>()
        .AddTransient<IStateRepository, DapperRepository>()
        .AddTransient<StateRepositories>();

public class StateRepositories
{
    public IStateRepository Local { get; }

    public IStateRepository SqlServer { get; }

    public StateRepositories(IEnumerable<IStateRepository> repositories)
    {
        Local = repositories.OfType<LocalRepository>().FirstOrDefault();
        SqlServer = repositories.OfType<DapperRepository>().FirstOrDefault();
    }
}