如何使用依赖注入正确管理这种情况

本文关键字:管理 情况 何使用 依赖 注入 | 更新日期: 2023-09-27 18:05:25

想象一下,你有一个网站,每个用户都可以在盒子里放一个代码,然后按"搜索"来查找有关产品的信息。代码将匹配模式:SHOPNAME-PROGRESSIVENUMBER,例如:EVERYDAYSHOES-002NEWGAMES-005

当用户按下"搜索"按钮时,我的代码将:

  1. 识别店铺
  2. 获取一个连接字符串以连接到数据库,每个商店的连接字符串都不同
  3. 使用该连接字符串调用该数据库上的查询

实现这一目标的第一件事是编写如下代码:

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
    }
}

我的问题是:

  1. 每次点击我的按钮都进行注册-解决是好是坏(以及为什么(
  2. 如果它很糟糕,我该如何重构它,使其相对于DI模式正确

对于第二个问题,我的想法是:

  1. 只需在每次点击按钮时调用Resolve override connectionString

  2. 解决所有可能的SQLProductInformationsProvider,将它们缓存在字典中,并使用所需的一个

  3. 从构造函数中删除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
}
相关文章: