首页 > 解决方案 > .Net core 依赖注入 - 带参数

问题描述

注意:此示例已简化

我有一个客户的联系表,想从数据库中检索特定的客户联系信息。我输入的代码 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)>()

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

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

解决方案


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

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

例如,假设您从声明中获取客户端 ID,因此您需要注入的类型是 IPrincipal:

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

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

旁注:您确定要为您的仓库使用 AddTransient 吗?通常,您希望在请求的生命周期内使用相同的 repo 对象(即 AddScoped)。


推荐阅读