依赖注射用而,视3和使用的服务模式的定位器
题
什么,一直缠着我,因为我读的一个回答另一个计算器的问题(精确的一种逃避我现在)其中一个用户表示喜欢的东西"如果你打电话服务定位,你们这么做是错误的。"
这是一个人有很高的声誉(以百万,我认为),使我倾向于认为这个人可能知道他们是怎么说的。我一直在使用迪对我的项目,因为我第一次开始学习对它以及它如何涉及单元的测试和什么不可以。这件事情我相当舒服的现在和我 想想 我知道我在做什么。
然而,有很多地方在那里我已经被使用的服务定位,以解决依赖关系在我的项目。一旦主要的例子来自我ModelBinder实现。
例的一个典型的粘合剂。
public class FileModelBinder : IModelBinder {
public object BindModel(ControllerContext controllerContext,
ModelBindingContext bindingContext) {
ValueProviderResult value = bindingContext.ValueProvider.GetValue("id");
IDataContext db = Services.Current.GetService<IDataContext>();
return db.Files.SingleOrDefault(i => i.Id == id.AttemptedValue);
}
}
不是一个真正的实施-只是一个简单的例子
由于ModelBinder的实现需要一个新实例,当一个粘合剂 第一 被请求,这是不可能的使用依赖注射的构造对这种特定执行情况。
它的这种方法在很多我的课程。另一个例子是,一个缓期运行的进程的一个方法每一个缓对象的到期在我的网站。我运行了一堆的数据库中调用并没有什么。有过我使用的一个服务定位,获得所需的依赖。
另一个问题,我国最近(我发布一个问题,在这里约)的是,我所有的控制器所需要的一个实例IDataContext我用二的-但是 一个 作方法需要一种不同的实例IDataContext.而幸运的是前来救援与命名的依赖。然而,这感觉就像一个临时搭配,而不是一个真正的解决方案。
我想我至少理解这一概念的分离的问题合理的,但似乎有根本性的错误我怎么了解依赖注射和服务定位模式-我不知道那是什么。
我目前的理解是-这可能是错误的,因为良好的是,至少在软,ControllerFactory看起来的构造为一个控制器和电话服务定位本身获得所需的依赖,然后通过他们。然而,我可以理解的是,不是所有类和什么没有一家工厂来创建它们。所以在我看来,一些服务定位的模式是可以接受...但是...
- 当它是不可接受的?
- 什么样的模式,我应该能看出来的时候我应该重新思考我是如何使用的服务定位器的行为模式?
- 是我ModelBinder执行错误的吗?如果是这样,什么,我需要了解修复它吗?
- 在另外一个问题线沿线的这一个用户 马昆特 建议一个抽象的工厂-这怎么有关?
我猜这就是它-我真的不能想到的任何其他问题,以帮助我理解但是任何额外的信息是极大的赞赏。
我的理解是,DI可能不是该回答的一切和我可能要去海里我如何实现这一点,但是,似乎工作的方式,我希望它有单元的测试和什么不可以。
我不是在寻找代码解决我如执行-我找到了解,寻找一个解释解决我有缺陷的理解。
我的愿望stackoverflow.com 有能力节约草案的问题。我还希望谁回答这个问题得到适当数量的名声回答这个问题,因为我认为我要求很多。谢谢,提前。
解决方案
考虑以下几点:
public class MyClass
{
IMyInterface _myInterface;
IMyOtherInterface _myOtherInterface;
public MyClass(IMyInterface myInterface, IMyOtherInterface myOtherInterface)
{
// Foo
_myInterface = myInterface;
_myOtherInterface = myOtherInterface;
}
}
这个设计我能够表达的依赖性要求我的类型。类型本身就是不负责知道如何化的任何的依赖性,他们给它(注)通过的任何解决机制是使用[通常IoC容器].鉴于:
public class MyClass
{
IMyInterface _myInterface;
IMyOtherInterface _myOtherInterface;
public MyClass()
{
// Bar
_myInterface = ServiceLocator.Resolve<IMyInterface>();
_myOtherInterface = ServiceLocator.Resolve<IMyOtherInterface>();
}
}
我们现在依赖于创造具体的实例,但通过国代表团对服务定位。在这个意义上,服务的位置,可以考虑一个 反模式 因为你不暴露的依赖,但是你让问题可以通过汇编泡入运行时间。(A好读的 在这里,).你隐藏的复杂性。
之间选择一个或另一个实际上取决于什么你的建筑的顶上和服务的提供。通常,如果你正在建立一个应用程序从头开始,我会选择迪所有的时间。它提高了维护,促进了模块化设计和试验种类型。但是,考虑ASP.NET MVC3作为一个例子,你可以容易地实现SL作为其融入到设计之中。
你总是可以去一个复合材料设计,可以使用IoC/DI与SL,更喜欢采用的 共同事务的定位器.你零部件可能有线通过DI,但通过SL。你甚至可以扔组成的混合和利用东西喜欢的管理扩展框架(其本身的支持,但也可以有线的其他IoC集装箱或服务定位器).这是一个大的设计做出的选择,通常我的建议将用于IoC/DI在可能的情况。
你具体设计,我不会说是错误的。在该实例中,你的代码不是负责创建一个实例模型的粘合剂本身,这是该框架,所以你有没有控制, 但 你使用的服务定位器也许可以容易地改变了访问IoC容器。 但行动的呼吁解决在国际奥委会的容器...你会不考虑服务的位置?
与一个抽象的工厂式的工厂的专门建立具体类型。你不注册类型的分辨率,你本质上是注册一个抽象的工厂,建立任何类型的你可能需要。有一个服务定位器是设计来 定位服务 和返回这些实例。类似的,从一个公约的观点,但非常不同的行为。