【问题标题】:Inject different implementations that have same interface in multiple constructor parameters在多个构造函数参数中注入具有相同接口的不同实现
【发布时间】:2018-07-21 15:16:50
【问题描述】:

我的目标是创建一个包含接口的不同实现的对象,并在运行时选择要使用的实现。我在 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?还是有更好的方法来实现我的目标?

【问题讨论】:

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


【解决方案1】:

您可以单独注册您的IStateRepository,然后注入IEnumerable&lt;IStateRepository&gt;,它会注入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();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-26
    • 1970-01-01
    • 2021-11-02
    相关资源
    最近更新 更多