代码之家  ›  专栏  ›  技术社区  ›  Beep beep

处理在单个函数调用中更改的与IOC的依赖关系

  •  2
  • Beep beep  · 技术社区  · 14 年前

    我们正试图找出如何为服务类可以根据其使用方式具有不同依赖性的情况设置依赖性注入。在我们的特定情况下,我们有一个Web应用程序,其中95%的时间连接字符串对于整个请求都是相同的(这是一个Web应用程序),但有时它可以更改。

    例如,我们可能有两个具有以下依赖关系的类(简化版本-服务实际上有4个依赖关系):

    public LoginService (IUserRepository userRep)
    {
    }
    
    public UserRepository (IContext dbContext)
    {
    }
    

    在我们的IOC容器中,除了我有类似这样的上下文(不是实际的代码,它来自内存…这是结构图): x.forRequestedType()。使用()) .withctorarg(“connectionString”).equalto(会话[“connstring”]);

    对于我们95%的Web应用程序,这是完美的。但是,我们有一些管理类型的函数必须跨数千个数据库(每个客户机一个)运行。基本上,我们想这样做:

    public CreateUserList(IList<string> connStrings)
    {
       foreach (connString in connStrings)
       {
           //first create dependency graph using new connection string 
           ????       
           //then call service method on new database
           _loginService.GetReportDataForAllUsers();
       }
    }
    

    我的问题是:我们如何通过循环每次创建新的依赖关系图,同时维护一些易于测试的东西?

    4 回复  |  直到 14 年前
        1
  •  2
  •   Bryan Watts    14 年前

    要将对象的创建推迟到运行时,可以使用工厂:

    public interface ILoginServiceFactory
    {
        ILoginService CreateLoginService(string connectionString);
    }
    

    用途:

    public void CreateUserList(IList<string> connStrings)
    {
        foreach(connString in connStrings)
        {
            var loginService = _loginServiceFactory.CreateLoginService(connString);
    
            loginService.GetReportDataForAllUsers();
        }
    }
    
        2
  •  0
  •   Joshua Flanagan    14 年前

    在循环中,执行以下操作:

    container.With("connectionString").EqualTo(connString).GetInstance<ILoginService>()
    

    其中“connectionString”是ILoginservice具体实现上的字符串构造函数参数的名称。

        3
  •  0
  •   Jeff Sternal    14 年前

    所以大多数 UserRepository 方法使用从会话中获取的单个连接字符串,但有几个方法需要针对连接字符串列表进行操作?

    您可以通过提升连接字符串依赖项来解决此问题。 IContext 到存储库并添加两个附加依赖项-上下文工厂和存储库可能需要执行其工作的所有可能连接字符串的列表:

    public UserRepository(IContextFactory contextFactory, 
                          string          defaultConnectionString, 
                          List<string>    allConnectionStrings)
    

    然后它的每个方法都可以构建尽可能多的 图标文本 需要的实例:

    // In UserRepository
    
    public CreateUserList() {
        foreach (string connString in allConnectionStrings) {
            IContext context = contextFactory.CreateInstance(connString);
            // Build the rest of the dependency graph, etc. 
            _loginService.GetReportDataForAllUsers();
        }
    }
    
    public LoginUser() {
        IContext context = contextFactory.CreateInstance(defaultConnectionString);
        // Build the rest of the dependency graph, etc.
    }
    
        4
  •  0
  •   Beep beep    14 年前

    我们最终只是创建了一个具体的上下文并注入它,然后更改创建了一个包装类来更改上下文的连接字符串。似乎工作得很好。