1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > ASP.NET MVC IOC之Unity攻略

ASP.NET MVC IOC之Unity攻略

时间:2023-08-09 03:02:26

相关推荐

ASP.NET MVC IOC之Unity攻略

文章看着也不错,拿来分享给大家(转载)

原文地址/pro/html/07/17685.html

一、你知道IOC与DI吗?

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

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

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

view sourceprint?01.publicclassSqlServerDal02.{03.publicvoidDelete()04.{05.Console.WriteLine('删除表中某个订单信息!');06.}07.}08.09.publicclassOrder10.{11.privatereadonly SqlServerDal dal =newSqlServerDal();12.publicvoidDelete()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 DIPTest23.{24.classProgram25.{26.staticvoidMain(string[] args)27.{28.Order order =newOrder();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.publicinterfaceIDataAccess2.{3.voidDelete();4.}

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

view sourceprint?1.publicclassSqlServerDal:IDataAccess2.{3.publicvoidDelete()4.{5.Console.WriteLine('删除表中某个订单信息!');6.}7.}

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

view sourceprint?01.publicclassOrder02.{03.privateIDataAccess da;//构造函数注入04.publicOrder(IDataAccess ida)05.{06.da = ida;07.}08.publicvoidDelete()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 IOCDemo07.{08.classProgram09.{10.staticvoidMain(string[] args)11.{12.SqlServerDal dal =newSqlServerDal();//在Order类外部创建依赖对象13.Order order =newOrder(dal);//通过构造函数注入依赖14.order.Delete();15.Console.Read();16.}17.}18.}

(2)属性注入

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

view sourceprint?01.publicclassOrder02.{03.privateIDataAccess _da;04.//属性,接受依赖05.publicIDataAccess da06.{07.set { _da = value; }08.get {return_da; }09.}10.publicvoidDelete()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 IOCDemo07.{08.classProgram09.{10.staticvoidMain(string[] args)11.{12.AccessDal dal =newAccessDal();//在外部创建依赖对象13.Order order =newOrder();14.order.da = dal;//给属性赋值15.order.Delete();16.Console.Read();17.}18.}19.}

(3)接口注入

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

view sourceprint?1.publicinterfaceIDependent2.{3.voidSetDependence(IDataAccess ida);//设置依赖项4.}

用依赖类实现这个接口:

view sourceprint?01.publicclassOrder : IDependent02.{03.privateIDataAccess _ida;04.publicvoidSetDependence(IDataAccess ida)05.{06._ida = ida;07.}08.publicvoidDelete()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 IOCDemo06.{07.classProgram08.{09.staticvoidMain(string[] args)10.{11.AccessDal dal =newAccessDal();//在Order外部创建依赖对象12.Order order =newOrder();13.order.SetDependence(dal);//传递依赖14.order.Delete();15.Console.Read();16.}17.}18.}

3、IoC容器

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

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

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

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

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

二、Unity的使用

1、Unity是个什么东东?

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

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

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

2、Unity入门

您可以访问/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.publicinterfaceIClass05.{06.string ClassName { get; set; }07.voidShowInfo();08.}09.10./// <summary>11./// 计科班12./// </summary>13.publicclassCbClass : IClass14.{15.publicstring ClassName { get; set; }16.publicvoidShowInfo()17.{18.Console.WriteLine('计科班:{0}', ClassName);19.}20.}21.22./// <summary>23./// 电商班24./// </summary>25.publicclassEcClass : IClass26.{27.publicstring ClassName { get; set; }28.publicvoidShowInfo()29.{30.Console.WriteLine('电商班:{0}', ClassName);31.}32.}

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

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

A、创建一个UnityContainer对象

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

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

注入代码如下:

view sourceprint?01.publicstaticvoidContainerCodeTest()02.{03.IUnityContainer container =newUnityContainer();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:///practices//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.publicstaticvoidContainerConfiguration()2.{3.IUnityContainer container =newUnityContainer();//获取指定名称的配置节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.publicstaticvoidContainerConfigurationFromFile(string configFile)02.{03.//根据文件名获取指定config文件04.var fileMap =newExeConfigurationFileMap { ExeConfigFilename = configFile };05.//从config文件中读取配置信息06.Configuration configuration =07.ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);08.var unitySection = (UnityConfigurationSection)configuration.GetSection('unity');09.var container =newUnityContainer().LoadConfiguration(unitySection,'FirstClass');10.IClass classInfo = container.Resolve<IClass>('ec');11.classInfo.ShowInfo();12.}

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

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

代码示例如下:

view sourceprint?01.publicstaticvoidRegisterInstance()02.{03.IClass myClass =newMyClass();04.IClass yourClass =newYourClass();05.//为myClass实例注册默认实例06.container.RegisterInstance<IClass>(myClass);07.//为yourClass实例注册命名实例,同RegisterType08.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.publicstaticvoidTransientLifetimeManagerCode()02.{03.//以下2种注册效果是一样的04.container.RegisterType<IClass, MyClass>();05.container.RegisterType<IClass, MyClass>(newTransientLifetimeManager());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.publicstaticvoidTransientLifetimeManagerConfiguration()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.publicstaticvoidContainerControlledLifetimeManagerCode()02.{03.IClass myClass =newMyClass();04.//以下2种注册效果是一样的05.container.RegisterInstance<IClass>('ccl', myClass);06.container.RegisterInstance<IClass>('ccl', myClass,newContainerControlledLifetimeManager());07.container.RegisterType<IClass, MyClass>(newContainerControlledLifetimeManager());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>

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

三、 MVC与Unity

说了这么多Unity,主要还是想将其用到 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.IOC09.{10.publicclassUnityDependencyResolver : IDependencyResolver11.{12.IUnityContainer container;13.14.publicUnityDependencyResolver(IUnityContainer container)15.{16.this.container = container;17.}18.19.publicobject GetService(Type serviceType)20.{21.if(!this.container.IsRegistered(serviceType))22.{23.returnnull;24.}25.returncontainer.Resolve(serviceType);26.}27.28.publicIEnumerable<object> GetServices(Type serviceType)29.{30.returncontainer.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.IOC11.{12.publicclassUnityControllerFactory : DefaultControllerFactory13.{14.IUnityContainer container;15.publicUnityControllerFactory(IUnityContainer container)16.{17.this.container = container;18.}19.20.protectedoverride IController GetControllerInstance(RequestContext reqContext, Type controllerType)21.{22.returncontainer.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.BootStrapper12.{13.publicclassBootstrapper14.{15.publicstaticIUnityContainer Init()16.{17.var container = BuildUnityContainer();18.DependencyResolver.SetResolver(newUnityDependencyResolver(container));19.returncontainer;20.}21.22.privatestaticIUnityContainer BuildUnityContainer()23.{24.var container =newUnityContainer();25.26.UnityConfigurationSection configuration = (UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName);27.configuration.Configure(container,'defaultContainer');28.29.returncontainer;30.}31.32.}33.}

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

view sourceprint?01.publicclassMvcApplication : System.Web.HttpApplication02.{03.protectedvoidApplication_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.Models07.{08.publicclassStudent09.{10.publicintId { get; set; }11.publicstring Name { get; set; }12.publicstring Graduation { get; set; }13.publicstring School { get; set; }14.publicstring 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.Models07.{08.publicinterfaceIStudentRepository09.{10.IEnumerable<Student> GetAll();11.Student Get(intid);12.Student Add(Student item);13.bool Update(Student item);14.bool Delete(intid);15.}16.}

view sourceprint?01.using System;02.using System.Collections.Generic;03.using System.Linq;04.using System.Web;05.06.namespace UnityOfMVC.Models07.{08.publicclassStudentRepository : IStudentRepository09.{10.privateList<Student> Articles =newList<Student>();11.12.publicStudentRepository()13.{14.//添加演示数据15.Add(newStudent { Id =1, Name ='张三', Major ='软件工程', Graduation ='', School ='西安工业大学'});16.Add(newStudent { Id =2, Name ='李四', Major ='计算机科学与技术', Graduation ='', School ='西安工业大学'});17.Add(newStudent { Id =3, Name ='王五', Major ='自动化', Graduation ='', School ='西安工业大学'});18.}19./// <summary>20./// 获取全部文章21./// </summary>22./// <returns></returns>23.publicIEnumerable<Student> GetAll()24.{25.returnArticles;26.}27./// <summary>28./// 通过ID获取文章29./// </summary>30./// <param name='id'></param>31./// <returns></returns>32.publicStudent Get(intid)33.{34.returnArticles.Find(p => p.Id == id);35.}36./// <summary>37./// 添加文章38./// </summary>39./// <param name='item'></param>40./// <returns></returns>41.publicStudent Add(Student item)42.{43.if(item ==null)44.{45.thrownewArgumentNullException('item');46.}47.Articles.Add(item);48.returnitem;49.}50./// <summary>51./// 更新文章52./// </summary>53./// <param name='item'></param>54./// <returns></returns>55.publicbool Update(Student item)56.{57.if(item ==null)58.{59.thrownewArgumentNullException('item');60.}61.62.intindex = Articles.FindIndex(p => p.Id == item.Id);63.if(index == -1)64.{65.returnfalse;66.}67.Articles.RemoveAt(index);68.Articles.Add(item);69.returntrue;70.}71./// <summary>72./// 删除文章73./// </summary>74./// <param name='id'></param>75./// <returns></returns>76.publicbool Delete(intid)77.{78.Articles.RemoveAll(p => p.Id == id);79.returntrue;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.Controllers09.{10.publicclassStudentController : Controller11.{12.readonly IStudentRepository repository;13.//构造器注入14.publicStudentController(IStudentRepository repository)15.{16.this.repository = repository;17.}18.19.publicActionResult Index()20.{21.var data = repository.GetAll();22.returnView(data);23.}24.25.}26.}

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。