如何使用依赖注入正确管理这种情况
本文关键字:管理 情况 何使用 依赖 注入 | 更新日期: 2023-09-27 18:05:25
想象一下,你有一个网站,每个用户都可以在盒子里放一个代码,然后按"搜索"来查找有关产品的信息。代码将匹配模式:SHOPNAME-PROGRESSIVENUMBER
,例如:EVERYDAYSHOES-002
或NEWGAMES-005
。
当用户按下"搜索"按钮时,我的代码将:
- 识别店铺
- 获取一个连接字符串以连接到数据库,每个商店的连接字符串都不同
- 使用该连接字符串调用该数据库上的查询
实现这一目标的第一件事是编写如下代码:
public interface IProductInformationsProvider
{
string GetProductName(int productCode);
}
public class SQLProductInformationsProvider : IProductInformationsProvider
{
...
public SQLProductInformationsProvider(
string connectionString,
ILogService logService)
{
...
}
public string GetProductName(int productCode)
{
...
}
}
为了获得IProductInformationsProvider
的距离,我会使用一个DI容器,并执行以下操作:
public void SearchButtonHandler(Dictionary<string, string> shopsConnectionStringsMap)
{
using (var container = new WindsorContainer())
{
container.Register(
Component.For<ILogService>()
.ImplementedBy<ConsoleLogService>());
container.Register(
Component.For<IProductInformationsProvider>()
.ImplementedBy<SQLProductInformationsProvider>()
.DependsOn(
Dependency.OnValue("connectionString", shopsConnectionStringsMap[parsedShopName]));
var productInformationsProvider = container.Resolve<IProductInformationsProvider>();
var productName = productInformationsProvider.GetProductName(theCode);
// Do something with productName
}
}
我的问题是:
- 每次点击我的按钮都进行注册-解决是好是坏(以及为什么(
- 如果它很糟糕,我该如何重构它,使其相对于DI模式正确
对于第二个问题,我的想法是:
只需在每次点击按钮时调用Resolve override
connectionString
解决所有可能的
SQLProductInformationsProvider
,将它们缓存在字典中,并使用所需的一个从构造函数中删除
connectionString
,并将其放在方法SetConnectionString(string connectionString)
上,但在这种情况下,我将不得不更加担心线程安全。
这三个想法都不能让我满意,它们让我觉得我误解了什么。我缺少什么/我该如何改变我的观点?
我认为一个解决方案是:
public interface IProductInformationsProvider
{
string GetProductName(int productCode);
}
public interface IConnectionStringProvider
{
string GetConnectionString(string shopName);
}
public class SQLProductInformationsProvider : IProductInformationsProvider
{
...
public SQLProductInformationsProvider(
IConnectionStringProvider connectionStringProvider,
ILogService logService)
{
...
}
public string GetProductName(string shopName, int productCode)
{
string connectionString = connectionStringProvider.GetConnectionString(shopName);
...
}
}
public void SearchButtonHandler(string shopName, int Code)
{
// _productInformationsProvider already resolved
var productName = _productInformationsProvider.GetProductName(shopName, Code);
// Do something with productName
}