使用和不使用 Unity 注入创建 class 的实例

Create an instance of class with and without injection with Unity

我有一个 API 控制器,在构造函数中 EmployeeService 的一个实例被实例化为 Unity

我想在 EmployeeService 的构造函数中注入 myTest 的值, 这意味着 Repository<Employee> 的实例将被创建并且 _myString 的内容将 "TestString"

如果可以怎么设置容器?

谢谢,

[RoutePrefix("api/employee")]
public class EmployeeController : ApiController
{
    string myTest = "TestString";
    readonly IEmployeeService _employeeService;

    public EmployeeController(IEmployeeService employeeService)
    {
        _employeeService = employeeService;
    }
}

public class EmployeeService : ServiceBase, IEmployeeService
{
    private readonly IRepository<Employee> _repoEmployee;
    private readonly string _myString;

    public EmployeeService(IRepository<Employee> repoEmployee, string myString)
    {
        _repoEmployee = repoEmployee;
        _myString = myString
    }
}

container
 .RegisterType<IRepository<Employee>, Repository<Employee>>()
 .RegisterType<IEmployeeService, EmployeeService>());

我的解决方案:

.RegisterType<IEmployeeService, EmployeeService>(
    new InjectionConstructor(
            typeof(IRepository<Employee>), 
            "MySetting"));

To use in the service class some parameters (keys) coming from the web.config. These parameters are read in the controller and send to the service class

控制器不应该关心从配置文件中读取。这样做违反了Single Responsibility Principle。这会导致可维护性问题;您已经遇到的问题,因为您的设计导致您在测试和配置 DI 库时遇到麻烦。

由于这些是配置值,它们在应用程序的生命周期内不会更改(更改配置文件将导致应用程序重新启动)。因此,控制器没有理由(一遍又一遍)读取它们。相反,您可以在启动期间读取它们一次并将它们注入需要该配置值的class。

如果有多个 classes 需要该配置值,则您的更改很高,以至于您缺少抽象。例如,与其将连接字符串注入许多 classes,不如考虑创建一个 ConnectionFactory,它对那些 classes 隐藏连接字符串,并允许根据请求创建 SqlConnection

但在你的情况下,我想象做这样的事情:

TimeSpan timeOut = TimeSpan.FromSeconds(Int32.Parse(
    ConfigurationManager.AppSettings["timeOut"]));

container.RegisterType<IRepository<Employee>, Repository<Employee>>();
container.RegisterType<IEmployeeService, EmployeeService>());
container.Register<IEmployeeService>(new InjectionFactory(c =>
    new EmployeeService(
        c.Resolve<IRepository<Employee>>(),
        timeOut)));

在启动时读取配置值有以下优点:

  • 它可以防止您的应用程序代码依赖于配置系统本身。这使您的代码更可重用、可测试和可维护。
  • 如果配置不正确,它允许应用程序在启动时快速失败。
  • 它允许您在测试套件中验证 DI 配置的正确性,而无需在单元测试项目中拥有完全相同的配置文件。