.Net 核心依赖注入 - 带参数
.Net core Dependency injection - with parameters
注意:此示例已被简化
我有一个客户的联系方式table,想从数据库中检索特定的客户联系信息。我输入的代码 belove 为我提供了所有联系方式。我想使用一个参数来只给我特定的客户联系人。
我像这样使用 IClientContactRepository 接口
public interface IClientContactRepository
{
IQueryable<ClientContactModel> ClientContacts { get; }
}
我用这个 class 通过 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;
}
在我的启动中class
services.AddTransient<IClientContactRepository, ClientContactRepository>();
我的问题是:我可以将客户端的 id 参数传递给构造函数吗?
我试过这个:给构造函数添加一个参数
public ClientContactRepository(IConfiguration config, int clientId)
并尝试启动 class。
services.AddTransient<IClientContactRepository, ClientContactRepository(int,i)>()
没用....
有人可以帮我传递参数吗?
是的,但是您从哪里获取客户端 ID - 它是一个在应用程序的生命周期内保持静态的配置值吗?如果是这样,您可以使用接受工厂委托的 AddTansient 方法重载来创建对象。
更好的方法(将涵盖所有用例)是使用 DI 容器注册可以提供该信息的类型(如果不存在此类类型,则创建一个)并将其用作存储库构造函数中的参数。
举个例子,假设您从声明中获取客户 ID,那么您需要注入的类型是 IPrincipal:
services.AddScoped<IPrincipal>(
provider => provider.GetService<IHttpContextAccessor>()
.HttpContext
.User);
然后您可以将 IPrincipal 注入您的回购构造函数并检索客户端 ID。更好的方法是创建您自己的类型“ClientIdAccessor”,它负责提供客户端 ID。然后,在测试您的存储库时,您将不会依赖 IPrincipal,并且这种新类型的实现将仅依赖于外部库来实现您的 asp.net 核心实现。
旁注:您确定要为您的存储库使用 AddTransient 吗?通常您希望在请求的生命周期内使用相同的 repo 对象(即 AddScoped)。
注意:此示例已被简化
我有一个客户的联系方式table,想从数据库中检索特定的客户联系信息。我输入的代码 belove 为我提供了所有联系方式。我想使用一个参数来只给我特定的客户联系人。
我像这样使用 IClientContactRepository 接口
public interface IClientContactRepository
{
IQueryable<ClientContactModel> ClientContacts { get; }
}
我用这个 class 通过 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;
}
在我的启动中class
services.AddTransient<IClientContactRepository, ClientContactRepository>();
我的问题是:我可以将客户端的 id 参数传递给构造函数吗?
我试过这个:给构造函数添加一个参数
public ClientContactRepository(IConfiguration config, int clientId)
并尝试启动 class。
services.AddTransient<IClientContactRepository, ClientContactRepository(int,i)>()
没用.... 有人可以帮我传递参数吗?
是的,但是您从哪里获取客户端 ID - 它是一个在应用程序的生命周期内保持静态的配置值吗?如果是这样,您可以使用接受工厂委托的 AddTansient 方法重载来创建对象。
更好的方法(将涵盖所有用例)是使用 DI 容器注册可以提供该信息的类型(如果不存在此类类型,则创建一个)并将其用作存储库构造函数中的参数。
举个例子,假设您从声明中获取客户 ID,那么您需要注入的类型是 IPrincipal:
services.AddScoped<IPrincipal>(
provider => provider.GetService<IHttpContextAccessor>()
.HttpContext
.User);
然后您可以将 IPrincipal 注入您的回购构造函数并检索客户端 ID。更好的方法是创建您自己的类型“ClientIdAccessor”,它负责提供客户端 ID。然后,在测试您的存储库时,您将不会依赖 IPrincipal,并且这种新类型的实现将仅依赖于外部库来实现您的 asp.net 核心实现。
旁注:您确定要为您的存储库使用 AddTransient 吗?通常您希望在请求的生命周期内使用相同的 repo 对象(即 AddScoped)。