ASP.NET MVC–DI(IoC)

今天的主题是ASP.NET MVC中的依赖注入这些事,依赖注入开始是叫作IoC也就是控制反转了,后来被rename了。废话到此结束。那么咱们为何要在ASP.NET MVC中时候DI呢?这DI有什么神奇的地方让ASP.NET MVC如此的爱它。为了解决这个问题呢,咱们先来看看,为何要依赖注入。其实在MVC中一个重要的特征就是关注分离,咱们但愿咱们的应用程序尽量的相互独立,尽量的减小彼此的依赖,一个理想的应用程序应当是一个组件能够不知道或者说不关心其它组件的存在,可是能够经过一个公开的接口能够调用其它的组件。这也就是所谓的松耦合。css

这里能够举一个很简单的例子说明。好比我定义了一个接口IprintStr,在这个接口里就是一个方法,string printName(string name);以后呢,咱们再定义一个类来继承这个接口:printStr:IprintStr.类的具体实现我这里再也不累赘。如今呢咱们要实现这个类提供的服务操做,咱们再定义一个类。叫作execute.cs咱们在这个execute.cs类中能够这么写:IprintStr str = new printStr(); string myName = str.printName(“David Zhang”);以后输出。到此这个例子就结束了。咱们接着来思考下。在咱们这个简单例子中execute类是经过IprintStr接口而不是直接经过printStr类实现,若是之后我这个execute要发生大的变化,要实现其余的功能,那么我能够这样写 IprintStr str = new xxxXX();也就是换掉new后面的对象。其余的代码保持不变。在这里呢咱们实现了必定的松耦合。在这个例子中呢,咱们的printStr类既依赖于IprintStr也依赖于execute类。在这里呢就会出现这样一个问题,加入有一天咱们这个printStr类出现了莫名其妙的问题,那么是否是咱们的execute这个类也要进行维护。这是很麻烦的一件事。最好的办法就是,这里的IprintStr,printStr和execute三个不一样的组件相互的分开,彼此之间没有半毛钱的关系。而咱们的依赖注入就是为了解决这样的问题!html

什么是依赖注入java


其实在应用程序中呢,在一个执行类中,不经过建立服务类的对象的实例,咱们就能够得到某个公开接口的对象的引用。也能够这么说依赖注入是一个过程,因为执行类只依赖于服务类的一个接口,而不依赖于具体的服务类,因此呢,在客户类中只定义一个注入点,在程序运行的时候,执行类不直接实例化服务类的具体兑现,而是执行类运行上下文的专门的组件来负责实例化服务类,以后呢,将其注入到执行类中。这样,执行类得以正常的运行。编程

依赖注入的类别mvc


这里我就说下setter注入和构造注入吧。其它的不怎么用框架

首先是setter注入:也就是在执行类中,设置一个服务类接口类型的数据成员,而且设置一个set方法做为注入点,这个set方法接受一个具体服务类实例做为参数,而且把它赋给服务类接口类型的数据成员 ide

 public class execute
    {
        IprintStr printStr;
        public void set_execute(IprintStr printStr)
        {
            this.printStr = printStr;
        }
 
        public string printNameFun(string name)
        {
            string  testExam= printStr.printName(name);
            return testExam;
        }
    }

还有一个就是构造注入(Constructor Injection)this

    public class execute
    {
        IprintStr printStr;
        public execute(IprintStr printStr)
        {
            this.printStr = printStr;
        }
 
        public string printNameFun(string name)
        {
            string  testExam= printStr.printName(name);
            return testExam;
        }
    }

构造注入呢,也就是setter注入方法变成了构造方法。这里要注意的是,构造注入只能注入一次,在程序运行期间,没有办法改变执行类中的服务类对象实例。spa

到了这里,咱们不得不谈到Ioc Container..net

用于实现依赖注入的框架或者是组件就是Ioc Container.好比java平台十分红熟的重量级Ioc Container Sping和一直到.net平台的Spring.net.以及一些轻量级的Ioc Container好比本文要说的unity和ninject。

咱们先说说ninject吧!


如何获得。咱们能够经过vs中的NuGet包管理器进行下在,它自动能够添加到相关的namespace到你的项目中,咱们要作的就是在要的时候,using下!我这里已经using了,下面就很简单了。

   1:  static void Main(string[] args)
   2:          {
   3:              IKernel ninjectKernel = new StandardKernel();
   4:              //绑定接口道实现该接口的类
   5:              ninjectKernel.Bind<IprintStr>().To<recName>();
   6:              //得到实现接口的对象实例
   7:              IprintStr iprintStr = ninjectKernel.Get<IprintStr>();
   8:              //建立recName实例而且实现注入依赖
   9:              string str = iprintStr.printName("This is David Zhang Home Page.");
  10:              Console.WriteLine(str);
  11:              Console.ReadKey();
  12:          }

这里咱们仍是应用上面咱们谈的例子。关键部分上面已经注释了!我在这里就再也不累赘了,这里的recName就是开始咱们说的实现IprintStr的printStr,由于有些变更没有改过来!转动眼睛。关于具体的ninject的API,你能够Google。我这里再也不多篇幅的说明。咱们就用在ASP.NET MVC 中使用的unity Container吧,由于最近的项目里用到了它,同时但愿这边博文给正在作项目的朋友们以参考。只当是抛砖引玉吧。

Ioc能够对ASP.NET MVC 的Controller进行注入,要想实现Controller的依赖注入,就须要让IoC容器接管Controller的建立,而ASP.NET MVC 3中提供的IDependencyResolver接口就为实现这个提供了可能。因此,咱们首先建立一个实现IDependencyResolver接口的UnityDependencyResolver类,

 

   1:    public class UnityDependencyResolver : IDependencyResolver
   2:      {
   3:          IUnityContainer container;
   4:          public UnityDependencyResolver(IUnityContainer container)
   5:          {
   6:              this.container = container;
   7:          }
   8:   
   9:          public object GetService(Type serviceType)
  10:          {
  11:              try
  12:              {
  13:                  return container.Resolve(serviceType);
  14:              }
  15:              catch
  16:              {
  17:                  return null;
  18:              }
  19:          }
  20:   
  21:          public IEnumerable<object> GetServices(Type serviceType)
  22:          {
  23:              try
  24:              {
  25:                  return container.ResolveAll(serviceType);
  26:              }
  27:              catch
  28:              {
  29:                  return new List<object>();
  30:              }
  31:          }
  32:      }

这里对null的说明:在IDependencyResolver.GetService(Type serviceType)的实现中,判断一下serviceType是否被注册,若是没有被注册,就返回null。ASP.NET MVC获得null返回值,会本身解析这个接口。好了,咱们如今实现了这个IDependencyResolver。还有一个很重要的一点就是你要告诉MVC,在这里咱们建立了unityDependencyResolver,他要被解析,咱们能够在Global.asax的Application_Start()中添加:

IUnityContainer container = new UnityContainer();
 DependencyResolver.SetResolver(new UnityDependencyResolver(container));

固然了,说到这里,还有一点咱们没有涉及,你们能够看到上面我用ninject写的一个小例子,它有一个ninjectkernel.Bind<Ixxx>().To<xxx>().这个通俗的时候也就是注册,世间万物都是类似的,咱们在unity中也有相似的,如:

container.RegisterType<Ixxx, xxx>();那么咱们如何进行注册呢,有连个办法:第一就是在你须要的Controller中进行相关的注册,或者将全部的注册相关的代码统一到一个类文件中, 好比类:DependencyRegisterType,将全部的注册写到一个静态的方法中,以后再Application_Start()中进行运行。最后一点就是在相关的Controller中要这样写:

[Dependency]
 public IxxxL _xxxL { get; set; }

以后进行相关的调用。编程效率那是大大的增长啊!!省去了很多new.

okay,That’s all.时间不早了,Good Night

关于本博文声明:


本博文属于原创博文,容许转载。但要保留原连接!因为时间仓促,没有细心校对,博文可能有些地方不完善或者说是有错误。欢迎雅正:)

博文部分参考:

http://www.cnblogs.com/dudu/archive/2011/06/09/unity_mvc_idependencyresolver.html

http://www.cnblogs.com/techborther/archive/2012/01/06/2313498.html

相关文章
相关标签/搜索