简体   繁体   English

如何注入变化的依赖

[英]How to inject a changing dependency

I'm new to dependency injection, I'm wondering how you would handle the following scenario. 我是依赖注入的新手,我想知道您将如何处理以下情况。 We have something like the following: 我们有如下内容:

public class DatabaseContext
{
  public string ConnectionString {get;}
}

public interface IDataAccess
{
  string GetString(int id);
}

public class DataAccessImpl : IDataAccess
{
  private DatabaseContext _context;
  public DataAccessImpl(DatabaseContext context)
  {
    this._context=context;
  }

  public string GetString(int id)
  {
    return "some data";
  }
}

For web applications each request could build up a different DatabaseContext to point to a different database. 对于Web应用程序,每个请求都可以建立不同的DatabaseContext来指向不同的数据库。 For windows forms we could change the current DatabaseContext. 对于Windows窗体,我们可以更改当前的DatabaseContext。 How does a di framework handle a dependency that can change? di框架如何处理可以改变的依赖关系? Such that when i request a IDataAccess it always has the appropriate/current DatabaseContext. 这样,当我请求IDataAccess时,它始终具有适当的/当前的DatabaseContext。

The approach that I've taken is not to inject a DataContext but a DataContext factory, a class with a method that returns a DataContext of the appropriate type. 我采用的方法不是注入DataContext,而是注入DataContext工厂,这是一个带有返回适当类型DataContext方法的类。 I have two constructors for, in my case, a controller class the default constructor and one that takes the factory (and other injected objects). 在我的情况下,我有两个构造函数,一个控制器类是默认构造函数,一个有工厂(和其他注入的对象)。 The default constructor simply calls the constructor with parameters with all the parameters null. 默认构造函数只是使用带有所有参数为null的参数调用构造函数。 The parameterized constructor creates objects of default types if the corresponding parameter is null. 如果相应的参数为null,则参数化的构造函数将创建默认类型的对象。

Using the factory allows my controller actions to create a new DataContext when invoked instead of having a single DataContext that exists throughout the life of the application. 使用工厂允许我的控制器动作在被调用时创建一个新的DataContext,而不是在应用程序的整个生命周期中都存在一个DataContext。 The factory could be built to return an existing context if available and create a new one as needed, but I prefer to scope them to a unit of work. 可以构建工厂以返回现有的上下文(如果可用)并根据需要创建一个新的上下文,但是我更喜欢将它们的范围限定为一个工作单元。

PS The factory actually produces a wrapper class around a DataContext, not the actual DataContext, as an interface (IDataContextWrapper). PS工厂实际上是围绕DataContext而不是实际的DataContext产生包装类,作为接口(IDataContextWrapper)。 This makes it much easier to mock the actual database out of my controller tests. 这使得从控制器测试中模拟实际数据库变得更加容易。 All of the above assumes LINQ/ASP.NET MVC, but the principles are generally applicable, I think. 上面所有这些都假定使用LINQ / ASP.NET MVC,但我认为这些原则通常适用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM