如何使用 Ninject 的构造函数注入将连接字符串传递给构造函数
How to pass a connection string to a constructor using Ninject's constructor injection
我最近发现了依赖注入框架 Ninject 并想在我的一些项目中开始使用它。
我了解如何设置基本的接口到具体实现的绑定,但我无法找到将参数传递给具体实现的构造函数的最佳方式。
示例:
假设我们有一个简单的界面来表示客户存储库:
interface ICustomerRepository
{
Customer GetCustomer(int CustomerID);
}
及其具体实现:
class CustomerRepository : ICustomerRepository
{
private string _connectionString { get; }
// Constructor
public CustomerRespository(string connectionString)
{
this._connectionString = connectionString;
}
// Implements ICustomerRepository.GetCustomer
public Customer GetCustomer(int CustomerID)
{
// logic to retrieve customer
}
}
为了完整起见,这里是客户存储库的客户端:
class CustomerManager
{
private ICustomerRepository _repo { get; }
public CustomerManager(ICustomerRepository repo)
{
this._repo = repo;
}
// ...
}
现在,我正在寻找将连接字符串传递给 CustomerRepository
的最佳方法。使用 Ninject 的文档,我发现我可以按如下方式设置基本绑定:
Bind<ICustomerRepository>().To<CustomerRepository>();
但是,此方法不允许我将连接字符串发送到 CustomerRepository
。
作为变通方法,我想我会尝试以下类似的方法。首先,我设置了基本的接口到实现绑定。然后,我为具体实现设置了一个特殊的绑定,使用工厂方法传入连接字符串。
Bind<ICustomerRepository>().To<CustomerRepository>();
Bind<CustomerRepository>().ToMethod(context => new CustomerRepository("<connection>"));
我遇到的唯一其他解决方案是使用 WithConstructorArgument
方法。这似乎是一个显而易见的选择,但我不确定我对使用 "magic strings" 定义参数名称的感觉如何。
Bind<ICustomerRepository>()
.To<CustomerRepository>()
.WithConstructorArgument(
"connectionString",
"<connection>");
- 还有其他方法可以将参数传递给具体实现的构造函数吗?
- 我可以遵循更好的具体实现模式来避免在构造函数中使用连接字符串吗?
我很感激任何见解。
WithConstructorArgument
也有匹配类型的重载,而不是参数的名称,这使得重构更安全。例子
用法:
Bind<ICustomerRepository>()
.To<CustomerRepository>()
.WithConstructorArgument("<connection>");
我在一个更大的项目上工作了几年,我们从未使用过名称匹配的参数,但总是输入匹配的参数。
我最近发现了依赖注入框架 Ninject 并想在我的一些项目中开始使用它。
我了解如何设置基本的接口到具体实现的绑定,但我无法找到将参数传递给具体实现的构造函数的最佳方式。
示例:
假设我们有一个简单的界面来表示客户存储库:
interface ICustomerRepository
{
Customer GetCustomer(int CustomerID);
}
及其具体实现:
class CustomerRepository : ICustomerRepository
{
private string _connectionString { get; }
// Constructor
public CustomerRespository(string connectionString)
{
this._connectionString = connectionString;
}
// Implements ICustomerRepository.GetCustomer
public Customer GetCustomer(int CustomerID)
{
// logic to retrieve customer
}
}
为了完整起见,这里是客户存储库的客户端:
class CustomerManager
{
private ICustomerRepository _repo { get; }
public CustomerManager(ICustomerRepository repo)
{
this._repo = repo;
}
// ...
}
现在,我正在寻找将连接字符串传递给 CustomerRepository
的最佳方法。使用 Ninject 的文档,我发现我可以按如下方式设置基本绑定:
Bind<ICustomerRepository>().To<CustomerRepository>();
但是,此方法不允许我将连接字符串发送到 CustomerRepository
。
作为变通方法,我想我会尝试以下类似的方法。首先,我设置了基本的接口到实现绑定。然后,我为具体实现设置了一个特殊的绑定,使用工厂方法传入连接字符串。
Bind<ICustomerRepository>().To<CustomerRepository>();
Bind<CustomerRepository>().ToMethod(context => new CustomerRepository("<connection>"));
我遇到的唯一其他解决方案是使用 WithConstructorArgument
方法。这似乎是一个显而易见的选择,但我不确定我对使用 "magic strings" 定义参数名称的感觉如何。
Bind<ICustomerRepository>()
.To<CustomerRepository>()
.WithConstructorArgument(
"connectionString",
"<connection>");
- 还有其他方法可以将参数传递给具体实现的构造函数吗?
- 我可以遵循更好的具体实现模式来避免在构造函数中使用连接字符串吗?
我很感激任何见解。
WithConstructorArgument
也有匹配类型的重载,而不是参数的名称,这使得重构更安全。例子
用法:
Bind<ICustomerRepository>()
.To<CustomerRepository>()
.WithConstructorArgument("<connection>");
我在一个更大的项目上工作了几年,我们从未使用过名称匹配的参数,但总是输入匹配的参数。