团结创造特定的实例

时间:2016-03-17 17:45:09

标签: c# asp.net asp.net-mvc dependency-injection unity-container

我目前正在使用.net 4.6,MVC 5和unity 4构建应用程序。我有一个如下所示的控制器:

public class ExamController: Controller {
 private IEducationService _eduService;    
 public ExamController(IEducationService eduService) {
  _eduService = eduService;
 }
}

Unity将服务注入:

container.RegisterType<IEducationService, EducationService>();

最近我们正在为这个需要其他服务的控制器添加其他Action方法。例如,如果我现在有ExperienceService,我可以将其添加到Unity并更改控制器的构造函数以获取它:

public ExamController(IEducationService eduService, IExperienceService _expService )

问题是我不希望它们一直都可用,它们应该基于调用哪个Action方法而可用。我可以为每个构建单独的构造函数,但是我不确定如何根据调用哪个Action方法让Unity创建一个而不是两个。

2 个答案:

答案 0 :(得分:2)

使用multiple constructors on injectables is anti-pattern

此外,constructors should be simple,因此担心创建未使用的额外对象是错误的(除非您违反此规则)。当构造函数中没有任何内容但是赋值语句时,创建对象非常便宜,因此注入1或甚至100多个可能不会对性能产生巨大影响。

您还应该限制控制器拥有的服务数量。如果您有超过3或4,您可能违反了单一责任原则,consider refactoring to facade services每个人都有一个责任。结果是你会得到一个对象图,它看起来更像金字塔顶部有一些依赖关系,而这些依赖关系将会有更多依赖关系,直到你到达没有依赖关系的底部。

相关:Rebuttal: Constructor over-injection anti-pattern

答案 1 :(得分:1)

您可以使用ServiceLocator简单地解决操作方法中您需要的依赖项,而不是将依赖项注入并可用于整个类:

var expService = ServiceLocator.Current.GetInstance(typeof(IExperienceService));

首先需要注册Unity的ServiceLocator:

ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(container));

Example

快速说明:服务定位器模式被视为反模式。