依赖注入 – 依赖注入与Ninject,MVC 3并使用服务定位器模式

前端之家收集整理的这篇文章主要介绍了依赖注入 – 依赖注入与Ninject,MVC 3并使用服务定位器模式前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
从我读到另一个stackoverflow问题的一个答案(确切的说,我现在在这里),一个用户表达了一些类似“如果你打电话给服务定位器,你做错了”的东西.

这是一个声望很高的人(在数十万,我想),所以我倾向于认为这个人可能会知道他们在说什么.自从我第一次开始学习以及与单元测试相关的程度,我一直在为自己的项目使用DI.这是我现在相当舒服的事情,我想我知道我在做什么.

但是,有很多地方我一直在使用服务定位器来解决项目中的依赖关系.一旦我们的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的实现在首次请求Binder时需要一个新的实例,所以不可能在此特定实现的构造函数上使用依赖注入.

在很多课上就是这样.另一个例子是缓存到期过程,当缓存对象在我的网站中到期时运行方法.我运行一堆数据库调用,而不是.我也在使用服务定位器来获取所需的依赖关系.

最近我发现另一个问题(我在这里发布了一个问题)是所有我的控制器都需要一个IDataContext的实例,我使用了DI – 但是一个动作方法需要一个不同的IDataContext实例.幸运的是,Ninject以命名的依赖来救援.然而,这感觉像是一个污泥,而不是一个真正的解决方案.

我以为我至少理解了关注分离的概念,但是我理解依赖注入和服务定位器模式似乎有些根本错了 – 我不知道是什么.

我现在理解的方式 – 这也可能是错误的 – 至少在MVC中,ControllerFactory会为控制器寻找一个构造函数,并调用服务定位器本身获取所需的依赖关系,然后将它们传入.,我可以明白,并不是所有的课程和没有一个工厂来创建它们.所以在我看来,一些服务定位器模式是可以接受的…但…

>什么时候不能接受?
>当我应该重新思考我如何使用服务定位器模式时,应该怎样看待什么样的模式?
>我的ModelBinder实现错误?如果是这样,我需要学习如何解决它?
>在另一个问题沿着这个用户Mark Seemann推荐一个抽象工厂 – 这是如何相关的?

我想是这样 – 我不能真正想到任何其他问题,以帮助我的理解,但任何额外的信息是非常感谢.

我明白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>();
  }
}

我们的课程现在依赖于创建特定实例,但是通过委派给服务定位器.在这个意义上,服务位置可以被认为是一种反模式,因为您不会暴露依赖关系,但是您可以通过编译来捕获可以通过编译触发运行时的问题. (好阅读是here).你隐藏复杂性

一个或另一个之间的选择真的取决于你的建筑物和它提供的服务.通常,如果您从零开始构建应用程序,我会一直选择DI.它提高了可维护性,促进了模块化,使测试类型变得更加容易.但是,以ASP.NET MVC3为例,您可以轻松地将SL作为烘焙设计实现.

您可以随时使用复合设计,您可以在SL中使用IoC / DI,就像使用Common Services Locator一样.您的组件可以通过DI进行连接,但可以通过SL进行曝光.您甚至可以将组合投入组合中,并使用像Managed Extensibility Framework(本身支持DI,但也可以连接到其他IoC容器或服务定位器)之类的东西.这是一个很大的设计选择,一般来说我的建议可能是IoC / DI.

你的具体设计我不会说是错的.在这种情况下,您的代码不负责创建模型绑定器本身的实例,这取决于框架,因此您无法控制,但是您可能会轻易更改使用服务定位器以访问IoC容器.但是在IoC容器上调用解决方案的行为你不会认为该服务位置?

凭借抽象的工厂模式,工厂专门制作特定类型.您不注册解析类型,您实际上注册一个抽象工厂,并构建您可能需要的任何类型.使用服务定位器,它旨在定位服务并返回这些实例.从常规的角度来看,行为类似,但行为差异很大.

原文链接:https://www.f2er.com/javaschema/281878.html

猜你在找的设计模式相关文章