.Net核心依赖项注入-带参数

时间:2019-04-07 15:37:12

标签: c# .net asp.net-core-2.0

注意:此示例已简化

我有一个客户的联系表,想从数据库中检索特定的客户联系信息。我输入belove的代码为我带来了所有联系方式。我只想使用一个参数来带给我特定的客户联系人。

我这样使用IClientContactRepository接口

public interface IClientContactRepository
{
    IQueryable<ClientContactModel> ClientContacts { get; }
}

我使用此类通过dapper从数据库中检索数据

public class ClientContactRepository : IClientContactRepository
{
    private readonly IConfiguration configuration;
    private List<ClientContactModel> ClientContactList {get;set;}


    public ClientContactRepository(IConfiguration config)
    {
        configuration = config;

        SqlConnection conn = new SqlConnection(configuration["ConnectionString"]);

        using (var connection = conn)
        {
            ClientContactList = connection.Query<ClientContactModel>("Select * FROM ContactTable ").ToList();
        }
    }
    public IQueryable<ClientContactModel> ClientContacts => ClientContactList;
}

在我的启动课程中

  services.AddTransient<IClientContactRepository, ClientContactRepository>();

我的问题是:我可以将客户端的id参数传递给构造函数。

我尝试过:向构造函数添加一个参数

  public ClientContactRepository(IConfiguration config, int clientId)

并尝试开始上课。

 services.AddTransient<IClientContactRepository, ClientContactRepository(int,i)>()

没有用... 有人可以帮我如何传递参数吗?

1 个答案:

答案 0 :(得分:3)

是的,但是您从哪里获得客户端ID-它是一个在应用程序的整个生命周期中都是静态的配置值吗?如果是这样,则可以使用接受工厂委托的AddTansient方法重载来创建对象。

更好的方法(涵盖所有用例)是在DI容器中注册可以提供该信息的类型(如果不存在这种类型,则创建一个),并将其用作回购构造函数中的参数。

例如,假设您从索赔中获得了客户ID,因此您需要注入的类型是IPrincipal:

services.AddScoped<IPrincipal>(
    provider => provider.GetService<IHttpContextAccessor>()
        .HttpContext
        .User);

然后,您将把IPrincipal注入到您的repo构造函数中并检索客户端ID。更好的方法是创建自己的类型“ ClientIdAccessor”,该类型负责提供客户端ID。这样,在测试存储库时就不会依赖IPrincipal,并且这种新类型的实现将仅依赖于外部库来实现asp.net核心实现。

旁注:确定要在存储库中使用AddTransient吗?通常,您需要在请求的整个生命周期内使用相同的回购对象(即AddScoped)。