文章看着也不错,拿来分享给大家(转载)
原文地址 http://www.it165.net/pro/html/201407/17685.html

  • 一、你知道IOC与DI吗?

    1、IOC(Inversion of Control )——控制反转

    即依赖对象不在被依赖模块的类中直接通过new来获取

    先看看下面这段代码的问题~

    view sourceprint?
    01.public class SqlServerDal
    02.{
    03.public void Delete()
    04.{
    05.Console.WriteLine('删除表中某个订单信息!');
    06.}
    07.}
    08. 
    09.public class Order
    10.{
    11.private readonly SqlServerDal dal = new SqlServerDal();
    12.public void Delete()
    13.{
    14.dal.Delete();
    15.}
    16.}
    17. 
    18.using System;
    19.using System.Collections.Generic;
    20.using System.Linq;
    21.using System.Text;
    22.namespace DIPTest
    23.{
    24.class Program
    25.{
    26.static void Main(string[] args)
    27.{
    28.Order order = new Order();
    29.order.Delete();
    30.Console.Read();
    31.}
    32.}
    33.}

    关于以上例子的说明:

    (1)在Order类中,它依赖于具体的对象SqlServerDal,违反了依赖倒置的原则,即不论是高层还是底层,都应该依赖于抽象而不应该依赖于具体

    (2)如果需求有变:数据访问层换为OracleDal,那么这个时候,就要修改Order类的代码;如果数据访问层再次换为MySqlDal,那么还要继续修改Order类的代码......如果无休止的变下去,将会是一个噩梦,而且你不但要修改   Order里边的代码,可能你还要修改Product、Users等类里边的代码,因为它们也可能跟Order类是同样的情况

    怎么办呢?IOC啊~

    那如何IOC啊?使用DI啊~

    2、DIDependency Injection)——依赖注入

    DI是IoC的一种实现方式,就是将依赖对象的创建和绑定转移到被依赖对象类的外面来实现

    依赖注入分为:构造函数注入、属性注入和接口注入

    (1)构造函数注入

    首先,我们为数据访问类SqlServerDal定义一个抽象接口IDataAccess,并在IDataAccess接口中声明GetAll方法:

    view sourceprint?
    1.public interface IDataAccess
    2.{
    3.void Delete();
    4.}

    然后在SqlServerDal类中,实现IDataAccess接口:

    view sourceprint?
    1.public class SqlServerDal:IDataAccess
    2.{
    3.public void Delete()
    4.{
    5.Console.WriteLine('删除表中某个订单信息!');
    6.}
    7.}

    接下来,我们还需要修改Order类:

    view sourceprint?
    01.public class Order
    02.{
    03.private IDataAccess da;    //构造函数注入
    04.public Order(IDataAccess ida)
    05.{
    06.da = ida;
    07.}
    08.public void Delete()
    09.{
    10.da.Delete();
    11.}
    12.}

    下面是控制台程序调用的代码:

    view sourceprint?
    01.using System;
    02.using System.Collections.Generic;
    03.using System.Linq;
    04.using System.Text;
    05. 
    06.namespace IOCDemo
    07.{
    08.class Program
    09.{
    10.static void Main(string[] args)
    11.{
    12.SqlServerDal dal = new SqlServerDal();//在Order类外部创建依赖对象
    13.Order order = new Order(dal);//通过构造函数注入依赖
    14.order.Delete();
    15.Console.Read();
    16.}
    17.}
    18.}

    (2)属性注入

    属性注入就是通过属性来传递依赖。因此,我们首先需要在依赖类Order中定义一个属性:

    view sourceprint?
    01.public class Order
    02.{
    03.private IDataAccess _da;
    04.//属性,接受依赖
    05.public IDataAccess da
    06.{
    07.set { _da = value; }
    08.get { return _da; }
    09.}
    10.public void Delete()
    11.{
    12._da.Delete();
    13.}
    14.}

    下面是控制台程序调用的代码:

    view sourceprint?
    01.using System;
    02.using System.Collections.Generic;
    03.using System.Linq;
    04.using System.Text;
    05. 
    06.namespace IOCDemo
    07.{
    08.class Program
    09.{
    10.static void Main(string[] args)
    11.{
    12.AccessDal dal = new AccessDal();//在外部创建依赖对象
    13.Order order = new Order();
    14.order.da = dal;//给属性赋值
    15.order.Delete();
    16.Console.Read();
    17.}
    18.}
    19.}

    (3)接口注入

    相比构造函数注入和属性注入,用起来没有它们方便。首先定义一个接口,包含一个设置依赖的方法。

    view sourceprint?
    1.public interface IDependent
    2.{
    3.void SetDependence(IDataAccess   ida);//设置依赖项
    4.}

    用依赖类实现这个接口:

    view sourceprint?
    01.public class Order : IDependent
    02.{
    03.private IDataAccess _ida;
    04.public void SetDependence(IDataAccess   ida)
    05.{
    06._ida = ida;
    07.}
    08.public void Delete()
    09.{
    10._ida.Delete();
    11.}
    12.}

    下面是控制台程序调用的代码:

    view sourceprint?
    01.using System;
    02.using System.Collections.Generic;
    03.using System.Linq;
    04.using System.Text;
    05.namespace IOCDemo
    06.{
    07.class Program
    08.{
    09.static void Main(string[] args)
    10.{
    11.AccessDal dal = new AccessDal();//在Order外部创建依赖对象
    12.Order order = new Order();
    13.order.SetDependence(dal);//传递依赖
    14.order.Delete();
    15.Console.Read();
    16.}
    17.}
    18.}

    3、IoC容器

    前面所有的栗子中,我们都是通过手动的方式来创建依赖对象,并将引用传递给被依赖模块。比如:

    view sourceprint?
    1.SqlServerDal dal = new SqlServerDal();//在Order外部创建依赖对象
    2.Order order = new Order(dal);//通过构造函数注入依赖

    对于大型项目来说,相互依赖的组件比较多。如果还用手动的方式,自己来创建和注入依赖的话,显然效率很低,而且往往还会出现不可控的场面。因此,IoC容器就诞生了。IoC容器实际上是一个DI框架,它能简化我们的工作量。它包含以下几个功能:

    动态创建、注入依赖对象。 管理对象生命周期。 映射依赖关系。

    本篇我们使用微软框架组给提供的Unity来实现依赖注入,它是最流行的IOC容器之一

    二、Unity的使用

    1、Unity是个什么东东?

    Unit是微软patterns& practices组用C#实现的轻量级、可扩展的依赖注入容器,我们可以通过代码或者XML配置文件的形式来配置对象与对象之间的关系,在运行时直接调用Unity容器即可获取我们所需的对象,以便建立松散耦合的应用程序。

    对于小型项目:用代码的方式实现即可

    对于中大型项目:使用配置文件比较好

    2、Unity入门

    您可以访问http://unity.codeplex.com/releases得到最新版本的Unity,也可以直接在Nuget中获取到最新版本的Unity,或者下载微软的企业库,然后在项目中添加Microsoft.Practices.Unity.dll和Microsoft.Practices.Unity.Configuration.dll的引用

    这里用到的最重要的东东就是IUnityContainer 接口,它本身定义了很多方法,当然还有一些扩展方法,具体的接口定义这里就不说了,我们会经常用到IUnityContainer 接口的RegisterInstance、RegisterType、Resolve等方法。

    这里我举个栗子,首先定义如下接口,并用两个类来进行实现:

    view sourceprint?
    01./// <summary>
    02./// 班级接口
    03./// </summary>
    04.public interface IClass
    05.{
    06.string ClassName { get; set; }
    07.void ShowInfo();
    08.}
    09. 
    10./// <summary>
    11./// 计科班
    12./// </summary>
    13.public class CbClass : IClass
    14.{
    15.public string ClassName { get; set; }
    16.public void ShowInfo()
    17.{
    18.Console.WriteLine('计科班:{0}', ClassName);
    19.}
    20.}
    21. 
    22./// <summary>
    23./// 电商班
    24./// </summary>
    25.public class EcClass : IClass
    26.{
    27.public string ClassName { get; set; }
    28.public void ShowInfo()
    29.{
    30.Console.WriteLine('电商班:{0}', ClassName);
    31.}
    32.}

    (1)用编程方式实现注入

    使用Unity来管理对象与对象之间的关系可以分为以下几步:

    A、创建一个UnityContainer对象

    B、通过UnityContainer对象的RegisterType方法来注册对象与对象之间的关系

    C、通过UnityContainer对象的Resolve方法来获取指定对象关联的对象

    注入代码如下:

    view sourceprint?
    01.public static void ContainerCodeTest()
    02.{
    03.IUnityContainer container = new UnityContainer();
    04.//默认注册(无命名),如果后面还有默认注册会覆盖前面的
    05.container.RegisterType<IClass, CbClass>();
    06.//命名注册
    07.container.RegisterType<IClass, EcClass>('ec');
    08.//解析默认对象
    09.IClass cbClass = container.Resolve<IClass>();
    10.cbClass.ShowInfo();
    11.//指定命名解析对象
    12.IClass ecClass = container.Resolve<IClass>('ec');         
    13.ecClass.ShowInfo();
    14.//获取容器中所有IClass的注册的已命名对象
    15.IEnumerable<IClass> classList = container.ResolveAll<IClass>();
    16.foreach (var item in classList)
    17.{
    18.item.ShowInfo();
    19.}
    20.}

    (2)配置文件方式

    通过配置文件配置Unity信息需要有以下几个步骤:

    A、在配置文件<configSections> 配置节下注册名为unity的section

    B、在<configuration> 配置节下添加Unity配置信息

    C、在代码中读取配置信息,并将配置载入到UnityContainer中

    配置文件内容如下:

    view sourceprint?
    01.<?xml version='1.0' encoding='utf-8'?>
    02.<configuration>
    03.<configSections>
    04.<section name='unity' type='Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration'/>
    05.</configSections>
    06.<unity xmlns=http://schemas.microsoft.com/practices/2010/unity>
    07.<!--定义类型别名-->
    08.<aliases>
    09.<add alias='IClass' type='ConsoleApplication1.UnityDemo.IClass,ConsoleApplication1' />
    10.<add alias='CbClass' type='ConsoleApplication1.UnityDemo.CbClass,ConsoleApplication1' />
    11.<add alias='EcClass' type='ConsoleApplication1.UnityDemo.EcClass,ConsoleApplication1' />
    12.</aliases>
    13.<!--容器-->
    14.<container name='FirstClass'>
    15.<!--映射关系-->
    16.<register type='IClass'  mapTo='CbClass'></register>
    17.<register type='IClass'  mapTo='EcClass' name='ec'></register>
    18.</container>
    19.</unity>
    20.</configuration>

    注入代码如下:

    view sourceprint?
    1.public static void ContainerConfiguration()
    2.{   
    3.IUnityContainer container = new UnityContainer();//获取指定名称的配置节  
    4.UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection('unity');   
    5.container.LoadConfiguration(section, 'FirstClass');//获取特定配置节下已命名的配置节<container name='FirstClass'>下的配置信息
    6.IClass classInfo = container.Resolve<IClass>('ec');
    7.classInfo. ShowInfo();
    8.}

    注意:

    如果系统比较庞大,那么对象之间的依赖关系可能就会很复杂,最终导致配置文件变得很大,所以我们需要将Unity的配置信息从App.config或web.config中分离出来到某一个单独的配置文件中,比如Unity.config,然后将其作为参数传递给下面的方法,依然可以实现依赖注入:

    view sourceprint?
    01.public static void ContainerConfigurationFromFile(string configFile)
    02.{
    03.//根据文件名获取指定config文件
    04.var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = configFile };
    05.//从config文件中读取配置信息
    06.Configuration configuration =
    07.ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
    08.var unitySection = (UnityConfigurationSection)configuration.GetSection('unity');
    09.var container = new UnityContainer().LoadConfiguration(unitySection, 'FirstClass');
    10.IClass classInfo = container.Resolve<IClass>('ec');
    11.classInfo.ShowInfo();
    12.}

    3、使用Unity为已存在的对象注册关系

    在日常开发的过程中我们有时候会自己创建好一个对象,但是你又想对这个已经创建好的对象的生命周期进行管理,这个时候你可以使用Unity提供的RegisterInstance方法(有很多重载),由于RegisterInstance是对已存在的实例进行注册,所以无法通过配置文件来进行配置。

    代码示例如下:

    view sourceprint?
    01.public static void RegisterInstance()
    02.{
    03.IClass myClass = new MyClass();
    04.IClass yourClass = new YourClass();
    05.//为myClass实例注册默认实例
    06.container.RegisterInstance<IClass>(myClass);
    07.//为yourClass实例注册命名实例,同RegisterType
    08.container.RegisterInstance<IClass>('yourInstance', yourClass);
    09.container.Resolve<IClass>().ShowInfo();
    10.container.Resolve<IClass>('yourInstance').ShowInfo();
    11.}

    这段代码很简单,就是使用RegisterInstance方法将已存在的实例myClass、yourClass等注册到UnityContainer中,默认情况下其实用的是ContainerControlledLifetimeManager,这个生命周期是由UnityContainer来进行管理,UnityContainer会维护一个对象实例的强引用,当你将已存在的实例注册到UnityContainer后,每次通过Resolve方法获取对象都是同一对象,也就是单件实例(singleton instance),具体有关生命周期相关信息在下面进行介绍。

    注意是单实例哦~

    4、Unity中生命周期管理

    我们在系统中引入Unity主要就是想通过Unity来解除对象之间的依赖关系,方便我们根据配置调用到所需的对象,而Unity默认情况下会自动帮我们维护好这些对象的生命周期,可能Unity自动维护的生命周期并不总是我们想要的,这时我们就要根据具体的需求来更改这些对象的生命周期,下面就简单介绍一下Unity中内置的两个常用生命周期管理器,其他的生命周期管理器如果需要可以自己上网查看其详细说明。

    (1)TransientLifetimeManager瞬态生命周期,默认情况下,在使用RegisterType进行对象关系注册时如果没有指定生命周期管理器则默认使用这个生命周期管理器,这个生命周期管理器就如同其名字一样,当使用这种管理器的时候,每次通过ResolveResolveAll调用对象的时候都会重新创建一个新的对象

    代码如下:

    view sourceprint?
    01.public static void TransientLifetimeManagerCode()
    02.{
    03.//以下2种注册效果是一样的
    04.container.RegisterType<IClass, MyClass>();
    05.container.RegisterType<IClass, MyClass>(new TransientLifetimeManager());
    06.Console.WriteLine('-------TransientLifetimeManager Begin------');
    07.Console.WriteLine('第一次调用RegisterType注册的对象HashCode:' +
    08.container.Resolve<IClass>().GetHashCode());
    09.Console.WriteLine('第二次调用RegisterType注册的对象HashCode:' +
    10.container.Resolve<IClass>().GetHashCode());
    11.Console.WriteLine('-------TransientLifetimeManager End------');
    12.}

    如果是使用配置的方式,则需要在配置文件中注册关系的时候在<register>配置节下新增<lifetime>既可(如果不新增则默认使用TransientLifetimeManager),如果想使用其他的生命周期管理器,则更改此配置节即可!

    其中<lifetime>有3个参数:

    type,生命期周期管理器的类型,这边可以选择Unity内置的,也可以使用自定义的,其中内置的生命周期管理器会有智能提示 typeConverter,生命周期管理器转换类,用户自定义一个生命周期管理器的时候所创建一个转换器 value,初始化生命周期管理器的值

    如果用此生命周期管理器,则要在配置文件中新增的节点如下:

    view sourceprint?
    1.<register type='IClass' mapTo='MyClass'>
    2.<lifetime type='transient' />
    3.</register>

    注入代码如下:

    view sourceprint?
    01.public static void TransientLifetimeManagerConfiguration()
    02.{
    03.//获取指定名称的配置节
    04.UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection('unity');
    05.container.LoadConfiguration(section, 'FirstClass');
    06.Console.WriteLine('-------TransientLifetimeManager Begin------');
    07.Console.WriteLine('第一次调用RegisterType注册的对象HashCode:' +
    08.container.Resolve<IClass>('transient').GetHashCode());
    09.Console.WriteLine('第二次调用RegisterType注册的对象HashCode:' +
    10.container.Resolve<IClass>('transient').GetHashCode());
    11.Console.WriteLine('-------TransientLifetimeManager End------');
    12.}

    以上无论是代码还是配置的方式,运行之后都会发现实例的哈希码是不一样的,说明每次调用都是重新生成一个对象实例!
    (2)ContainerControlledLifetimeManager,容器控制生命周期管理,这个生命周期管理器是RegisterInstance默认使用的生命周期管理器,也就是单件实例,UnityContainer会维护一个对象实例的强引用,每次调用的时候都会返回同一对象,示例代码如下:

    view sourceprint?
    01.public static void ContainerControlledLifetimeManagerCode()
    02.{
    03.IClass myClass = new MyClass();
    04.//以下2种注册效果是一样的
    05.container.RegisterInstance<IClass>('ccl', myClass);
    06.container.RegisterInstance<IClass>('ccl', myClass, new ContainerControlledLifetimeManager());
    07.container.RegisterType<IClass, MyClass>(new ContainerControlledLifetimeManager());
    08.Console.WriteLine('-------ContainerControlledLifetimeManager Begin------');
    09.Console.WriteLine('第一次调用RegisterType注册的对象HashCode:' + container.Resolve<IClass>().GetHashCode());
    10.Console.WriteLine('第二次调用RegisterType注册的对象HashCode:' + container.Resolve<IClass>().GetHashCode());
    11.Console.WriteLine('第一次调用RegisterInstance注册的对象HashCode:' + container.Resolve<IClass>('ccl').GetHashCode());
    12.Console.WriteLine('第二次调用RegisterInstance注册的对象HashCode:' + container.Resolve<IClass>('ccl').GetHashCode());
    13.Console.WriteLine('-------ContainerControlledLifetimeManager End------');
    14.}

    运行之后都会发现实例的哈希码是一样的,说明是单实例的

    如果用此生命周期管理器,则要在配置文件中新增的节点如下:

    view sourceprint?
    1.<register type='IClass' mapTo='MyClass' name='ccl'>
    2.<lifetime type='singleton' />
    3.</register>

    注入代码与上例类似,这里不再列出

    三、ASP.NET MVC与Unity

    说了这么多Unity,主要还是想将其用到ASP.NET MVC的IOC中,其实很简单,大概就几个步骤搞定:

    1. 实现IDependencyResolver接口并通过DependencyResolver.SetResolver告知MVC,将部分类型实例解析工作交由IoC容器Unity来处理

    view sourceprint?
    01.using System;
    02.using System.Collections.Generic;
    03.using System.Linq;
    04.using System.Web;
    05.using System.Web.Mvc;
    06.using Microsoft.Practices.Unity;
    07. 
    08.namespace UnityOfMVC.IOC
    09.{
    10.public class UnityDependencyResolver : IDependencyResolver
    11.{
    12.IUnityContainer container;
    13. 
    14.public UnityDependencyResolver(IUnityContainer container)
    15.{
    16.this.container = container;
    17.}
    18. 
    19.public object GetService(Type serviceType)
    20.{
    21.if (!this.container.IsRegistered(serviceType))
    22.{
    23.return null;
    24.}
    25.return container.Resolve(serviceType);
    26.}
    27. 
    28.public IEnumerable<object> GetServices(Type serviceType)
    29.{
    30.return container.ResolveAll(serviceType);
    31.}
    32. 
    33.}
    34.}

    2、继承DefaultControllerFactory,重载GetControllerInstance方法,实现自己的UnityControllerFactory类,并通过IoC容器将之注册为IControllerFactory的实现

    view sourceprint?
    01.using System;
    02.using System.Collections.Generic;
    03.using System.Linq;
    04.using System.Web;
    05.using System.Web.Mvc;
    06.using System.Web.Routing;
    07.using Microsoft.Practices.Unity;
    08.using System.Web.SessionState;
    09. 
    10.namespace UnityOfMVC.IOC
    11.{
    12.public class UnityControllerFactory : DefaultControllerFactory
    13.{
    14.IUnityContainer container;
    15.public UnityControllerFactory(IUnityContainer container)
    16.{
    17.this.container = container;
    18.}
    19. 
    20.protected override IController GetControllerInstance(RequestContext reqContext, Type controllerType)
    21.{
    22.return container.Resolve(controllerType) as IController;
    23.}
    24.}
    25.}

    3、让我们开始弄一下配置文件

    view sourceprint?
    01.<configSections>
    02.<section name='unity' type='Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
    03.Microsoft.Practices.Unity.Configuration' />
    04.</configSections>
    05.<unity>
    06.<containers>
    07.<container name='defaultContainer'>
    08.<register type='UnityOfMVC.Models.IStudentRepository, UnityOfMVC' mapTo='UnityOfMVC.Models.StudentRepository, UnityOfMVC'/>
    09.<register type='System.Web.Mvc.IControllerFactory, System.Web.Mvc' mapTo='UnityOfMVC.IOC.UnityControllerFactory, UnityOfMVC'/>
    10.</container>
    11.</containers>
    12.</unity>

    4、用引导类Bootstrapper进行初始化工作

    view sourceprint?
    01.using System;
    02.using System.Collections.Generic;
    03.using System.Linq;
    04.using System.Web;
    05.using System.Configuration;
    06.using System.Web.Mvc;
    07.using Microsoft.Practices.Unity;
    08.using Microsoft.Practices.Unity.Configuration;
    09.using UnityOfMVC.IOC;
    10. 
    11.namespace UnityOfMVC.BootStrapper
    12.{
    13.public class Bootstrapper
    14.{
    15.public static IUnityContainer Init()
    16.{
    17.var container = BuildUnityContainer();
    18.DependencyResolver.SetResolver(new UnityDependencyResolver(container));
    19.return container;
    20.}
    21. 
    22.private static IUnityContainer BuildUnityContainer()
    23.{
    24.var container = new UnityContainer();
    25. 
    26.UnityConfigurationSection configuration = (UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName);
    27.configuration.Configure(container, 'defaultContainer');
    28. 
    29.return container;
    30.}
    31. 
    32.}
    33.}

    5、在函数Application_Start() 中进行真正的初始化工作

    view sourceprint?
    01.public class MvcApplication : System.Web.HttpApplication
    02.{
    03.protected void Application_Start()
    04.{
    05.AreaRegistration.RegisterAllAreas();
    06. 
    07.WebApiConfig.Register(GlobalConfiguration.Configuration);
    08.FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    09.RouteConfig.RegisterRoutes(RouteTable.Routes);
    10.BundleConfig.RegisterBundles(BundleTable.Bundles);
    11.AuthConfig.RegisterAuth();
    12. 
    13.BootStrapper.Bootstrapper.Init(); //就是这个东东     
    14.}
    15.}

    6、现在在你的MVC程序中注入依赖代码就ok了

    (1)首先声明一个Student学生类

    view sourceprint?
    01.using System;
    02.using System.Collections.Generic;
    03.using System.Linq;
    04.using System.Web;
    05. 
    06.namespace UnityOfMVC.Models
    07.{
    08.public class Student
    09.{
    10.public int Id { get; set; }
    11.public string Name { get; set; }
    12.public string Graduation { get; set; }
    13.public string School { get; set; }
    14.public string Major { get; set; }
    15.}
    16.}

    (2)然后声明仓储接口和其实现

    view sourceprint?
    01.using System;
    02.using System.Collections.Generic;
    03.using System.Linq;
    04.using System.Text;
    05. 
    06.namespace UnityOfMVC.Models
    07.{
    08.public interface IStudentRepository
    09.{
    10.IEnumerable<Student> GetAll();
    11.Student Get(int id);
    12.Student Add(Student item);
    13.bool Update(Student item);
    14.bool Delete(int id);
    15.}
    16.}

    view sourceprint?
    01.using System;
    02.using System.Collections.Generic;
    03.using System.Linq;
    04.using System.Web;
    05. 
    06.namespace UnityOfMVC.Models
    07.{
    08.public class StudentRepository : IStudentRepository
    09.{
    10.private List<Student> Articles = new List<Student>();
    11. 
    12.public StudentRepository()
    13.{
    14.//添加演示数据
    15.Add(new Student { Id = 1, Name = '张三', Major = '软件工程', Graduation = '2013年', School = '西安工业大学' });
    16.Add(new Student { Id = 2, Name = '李四', Major = '计算机科学与技术', Graduation = '2013年', School = '西安工业大学' });
    17.Add(new Student { Id = 3, Name = '王五', Major = '自动化', Graduation = '2013年', School = '西安工业大学' });
    18.}
    19./// <summary>
    20./// 获取全部文章
    21./// </summary>
    22./// <returns></returns>
    23.public IEnumerable<Student> GetAll()
    24.{
    25.return Articles;
    26.}
    27./// <summary>
    28./// 通过ID获取文章
    29./// </summary>
    30./// <param name='id'></param>
    31./// <returns></returns>
    32.public Student Get(int id)
    33.{
    34.return Articles.Find(p => p.Id == id);
    35.}
    36./// <summary>
    37./// 添加文章
    38./// </summary>
    39./// <param name='item'></param>
    40./// <returns></returns>
    41.public Student Add(Student item)
    42.{
    43.if (item == null)
    44.{
    45.throw new ArgumentNullException('item');
    46.}
    47.Articles.Add(item);
    48.return item;
    49.}
    50./// <summary>
    51./// 更新文章
    52./// </summary>
    53./// <param name='item'></param>
    54./// <returns></returns>
    55.public bool Update(Student item)
    56.{
    57.if (item == null)
    58.{
    59.throw new ArgumentNullException('item');
    60.}
    61. 
    62.int index = Articles.FindIndex(p => p.Id == item.Id);
    63.if (index == -1)
    64.{
    65.return false;
    66.}
    67.Articles.RemoveAt(index);
    68.Articles.Add(item);
    69.return true;
    70.}
    71./// <summary>
    72./// 删除文章
    73./// </summary>
    74./// <param name='id'></param>
    75./// <returns></returns>
    76.public bool Delete(int id)
    77.{
    78.Articles.RemoveAll(p => p.Id == id);
    79.return true;
    80.}
    81.}
    82.}

    (3)最后添加控制器StudentController,并注入依赖代码:

    view sourceprint?
    01.using System;
    02.using System.Collections.Generic;
    03.using System.Linq;
    04.using System.Web;
    05.using System.Web.Mvc;
    06.using UnityOfMVC.Models;
    07. 
    08.namespace UnityOfMVC.Controllers
    09.{
    10.public class StudentController : Controller
    11.{
    12.readonly IStudentRepository repository;
    13.//构造器注入
    14.public StudentController(IStudentRepository repository)
    15.{
    16.this.repository = repository;
    17.}
    18. 
    19.public ActionResult Index()
    20.{
    21.var data = repository.GetAll();
    22.return View(data);
    23.}
    24. 
    25.}
    26.}

    (4)最后为控制器StudentController的Index方法添加视图即可,这里不再详述,运行效果如下:

转载于:https://www.cnblogs.com/dahe718/p/4303882.html

ASP.NET MVC IOC之Unity攻略相关推荐

  1. ASP.NET MVC IOC 之AutoFac攻略

    转于:http://www.cnblogs.com/WeiGe/p/3871451.html 一.为什么使用AutoFac? 之前介绍了Unity和Ninject两个IOC容器,但是发现园子里用Aut ...

  2. 如何发布.Net MVC 网站项目(攻略集锦)

    转载自诗人江湖老,原文地址 参考文献 既然是攻略,就必然有参考文献,放在文章开头,以示敬意! 1.MVC项目发布步骤 2.未能从程序集加载"System.ServiceModel.Activ ...

  3. ASP.NET完整打包卸载更新攻略(By Installshield 2010)【转】

    - 前言 前阵子做了一个有关Installshield的OA 打包安装程序,用的版本Installshield 2010-Premier,具体功能的内容如下: 1.OA采用的是asp.net(C#)开 ...

  4. ASP.NET MVC 简单的分页思想与实现

    首先我们通过VS创建一个空的基于Razor视图引擎的ASP.NET MVC3 Web应用程序,命名为JohnConnor.Web 对创建过程或Razor不太了解的看官,请移步 ASP.NET MVC ...

  5. asp.net mvc fckeditor全攻略(补充:Controller中传值的问题)

    开篇仍然要叙述我的环境 环境说明: 软件环境:asp.net mvc3   +   vs2010 系统环境:windows xp sp3 浏览器: ie8(为了世界的和平,为了社会的稳定,为了不再被大 ...

  6. 想爱容易,相处难:当ASP.NET MVC爱上IoC

    也许你会问ASP.NET MVC为什么会爱上IoC? 相爱的理由常常很简单,就像一首歌中所唱--"只为相遇那一个眼神". 而ASP.NET MVC爱上IoC只为IoC能实现MVC控 ...

  7. ASP.NET MVC的Razor引擎:IoC在View激活过程中的应用

    在<ASP.NET MVC的Razor引擎:RazorView>介绍BuildManagerCompiledView的时候,我们谈到默认使用的ViewPageActivator使用当前注册 ...

  8. ASP.NET画图全攻略(下)

    我们在前面已经完成了饼图和条形图的自定义类,下面我们将要应用这些类了.   使用vs.net新建一个名为Insight_cs的Web应用程序,并且添加到刚才的Insight工程中.删除默认的webfo ...

  9. Asp.net C#制作PDF文件全攻略

    StreamWriter pPDF=new StreamWriter(filePath); ArrayList xRefs=new ArrayList(); float yPos =0f; long ...

  10. Unity性能优化全攻略

    #Unity性能优化全攻略 总结自Siki的性能优化. ##优化相关前提 ###Unity游戏安装包大/运行卡的原因 Mono虚拟机 解决这个问题 ###DrawCall https://zhuanl ...

最新文章

  1. P4755 Beautiful Pair (数据结构+分治)
  2. 使用STM32CubeMX,生成STM32F103ZE SPI3 HAL 工程
  3. Jupyterlab 插件安装后侧边栏找不到的解决
  4. qdialog 返回值_python-PyQt QDialog返回响应是或否
  5. web前端入门学习 css(4)(盒子模型)
  6. win32 输出文字时清除之前的_努力学习没效果?3个步骤,强化沟通输出,实现飞跃式成长...
  7. SwitchHosts!提示没有切换权限:C:\WINDOWS\system32\drivers\etc\host 文件无法修改
  8. Python生成带自定义信息和头像图片的二维码
  9. 如何在C中纯粹编写iOS应用程序
  10. 2021年11月_IEEE TRANSACTIONS ON MEDICAL IMAGING_科技前言热点调研表
  11. 华为数通NA-NP学习笔记(个人精简)
  12. 小程序和app究竟哪个好?
  13. 删除EFI系统分区(ESP)后Windows无法启动,重建引导分区并修复启动的过程
  14. 我爱 Ruby 的三十七个理由
  15. 09_Filter过滤器(访问所有资源前,首先执行自定义过滤器类的doFilter方法)_Listener监听器(监听域对象的改变)
  16. JS 日历插件 实现农历、节气 可自定义加班和休假
  17. 前端视频预览功能的实现
  18. ctfshow 萌新计划 writeup1-8
  19. 安装 office2007时出现:1706的错误-解决方案
  20. 一位算法工程师对自己工作的反思,写得挺实在的

热门文章

  1. centos 7 x86_64上安装staruml2.8.0
  2. python练习题4
  3. [转]介绍几个C#正则表达式工具
  4. 浏览器默认事件,事件监听,事件委托
  5. MATLAB 设置文件的相对路径
  6. spark读取hdfs数据本地性异常
  7. javascript闭包续
  8. MFC中给对话框重绘边框
  9. git 生成ssh key
  10. 用css实现图片翻转