为ASP.NET MVC创建一个基于Unity的ControllerFactory

来源:未知 责任编辑:智问网络 发表时间:2013-11-12 17:20 点击:

 

谈到IoC和ASP.NET的集成,很多人会先后想到Ninject,不过我们个人还是倾向于Unity。这篇文章简单地介绍如果创建基于Unity的ControllerFactory。如下面的代码所示,我们通过直接继承DefaultControllerFactory创建一个自定的UnityControllerFactory。构造函数指定的是配置的UnityContainer的名称,如果没有显式指定则采用默认的UnityContainer。在重写的GetControllerInstance方法中,直接调用IUnityContainer的Resolve方法根据Controller类型创建相应的对象。[源代码从这里下载]

   1: public class UnityControllerFactory: DefaultControllerFactory

   2: {

   3:     public IUnityContainer Container { get; private set; }

   4:     public UnityControllerFactory(string containerName = "")

   5:     {

   6:         IUnityContainer container = new UnityContainer();

   7:         UnityConfigurationSection configSection = ConfigurationManager.GetSection(UnityConfigurationSection.SectionName) as UnityConfigurationSection;

   8:         if (null == configSection && !string.IsNullOrEmpty(containerName))

   9:         {

  10:             throw new ConfigurationErrorsException("Cannot find <unity> configuration section");

  11:         }

  12: 

  13:         if (string.IsNullOrEmpty(containerName))

  14:         {

  15:             configSection.Configure(container);

  16:         }

  17:         else

  18:         {

  19:             configSection.Configure(container, containerName);

  20:         }

  21:         this.Container = container;

  22:     }

  23:     protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)

  24:     {

  25:         Guard.ArgumentNotNull(controllerType, "controllerType");

  26:         return (IController)this.Container.Resolve(controllerType);

  27:     }

  28: }

为了演示DefaultControllerFactory的作用,我们来创建一个简单的例子。假设我们要创建一个维护联系人的应用,我们通过具有如下定义的Contact类型表示联系人,而IContactRepository接口定义了一个从存储中获取所有联系人的GetAllContacts方法,DefaultContactRepository是对IContactRepository接口的实现。

   1: public class Contact

   2: {

   3:     public string Name { get; set; }

   4:     public string Gender { get; set; }

   5:     public string Address { get; set; }

   6: }

   7: 

   8: public interface IContactRepository

   9: {

  10:     IEnumerable<Contact> GetAllContacts();

  11: }

  12: 

  13: public class DefaultContactRepository : IContactRepository

  14: {

  15:     public IEnumerable<Contact> GetAllContacts()

  16:     {

  17:         yield return new Contact

  18:         {

  19:             Name = "Zhang San",

  20:             Gender = "Male",

  21:             Address = "#328, XingHu Street, Su Zhou, Jiang Su Province, PRC."

  22:         };

  23: 

  24:         yield return new Contact

  25:         {

  26:             Name = "Li Si",

  27:             Gender = "Female",

  28:             Address = "#328, Jin Ji Hu Road, Su Zhou, Jiang Su Province, PRC."

  29:         };

  30:     }

  31: }

我们在Web应用的主页显示联系人列表,为此我创建了如下一个HomeController。在这里我们演示的是构造器注入,所以我们通过构造函数指定的IContactRepository对象来初始化Repository属性。在Action方法Index中调用IContactRepository的GetAllContacts方法为对应的View指定Model。

   1: public class HomeController : Controller

   2: {

   3:     public IContactRepository Repository { get; private set; }

   4:     public HomeController(IContactRepository repository)

   5:     {

   6:         this.Repository = repository;

   7:     }

   8:     public ActionResult Index()

   9:     {

  10:         return View(this.Repository.GetAllContacts());

  11:     }

  12: }

Index.cshtml代码如下所示,这是一个Model类型为IEnumerable<Contact>的View,它将所有的联系人信息列出来。

   1: @model IEnumerable<Artech.Web.Mvc.Extensions.Contact>

   2: @{

   3:     ViewBag.Title = "Index";

   4: }

   5: 

   6: <h2>Contact List</h2>

   7: 

   8: <div>

   9: <ul>

  10: @foreach (var contact in this.Model)

  11: {

  12:     <li>

  13:         <h3>@contact.Name</h3>

  14:         <p>Gender: @contact.Gender</p>

  15:         <p>Address: @contact.Address</p>

  16:         <hr />

  17:     </li>

  18: }

  19: </ul>

  20: </div>

自定义的UnityContainerFactory的注册定义在Gloable.asax中。初次之外,额外需要做的是忽略掉针对favicon.ico的路由,否则程序运行将会失败。

   1: public class MvcApplication : System.Web.HttpApplication

   2: {

   3:     public static void RegisterGlobalFilters(GlobalFilterCollection filters)

   4:     {

   5:         filters.Add(new HandleErrorAttribute());

   6:     }

   7: 

   8:     public static void RegisterRoutes(RouteCollection routes)

   9:     {

  10:         routes.IgnoreRoute("favicon.ico");

  11:         routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

  12:         routes.MapRoute("Default", "{controller}/{action}/{id}",

  13:             new { controller = "Home", action = "Index", id = UrlParameter.Optional }

  14:         );

  15:     }

  16: 

  17:     protected void Application_Start()

  18:     {

  19:         AreaRegistration.RegisterAllAreas();

  20:         RegisterGlobalFilters(GlobalFilters.Filters);

  21:         RegisterRoutes(RouteTable.Routes);

  22: 

  23:         ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory());

  24:     }

  25: }

接口IContactRepository和DefualtContactRepository之间的映射关系定义在如下所示的<unity>配置中。

   1: <unity>

   2:   <alias alias="IContactRepository" type="Artech.Web.Mvc.Extensions.IContactRepository, UnityIntegration" />

   3:   <alias alias="DefaultContactRepository" type="Artech.Web.Mvc.Extensions.DefaultContactRepository, UnityIntegration" />

   4:   <container>

   5:     <register type="IContactRepository" mapTo="DefaultContactRepository"/>

   6:   </container>

   7: </unity>

通过浏览器访问Web应用的主页,将会得到如下所示的联系人列表。

 

 

image

 

 

作者:Artech

  

    发表评论
    请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
    用户名: 验证码:点击我更换图片
    最新评论 更多>>

    推荐热点

    • 浅析.NET下XML数据访问新机制
    • asp.net 面试+笔试题目第1/2页
    • C# 邮件地址是否合法的验证
    • asp.net 设置GridView的选中行的实现代码
    • C#高级编程:数据库连接[1]
    • 经典C++程序1
    • IIS 自动回收导致后台定时器失效的问题解决
    • ASP.NET&#160;GridView列表代码示例
    • Asp.net MVC源码分析--Action Filter的链式调用
    网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索
    Copyright © 2008-2015 计算机技术学习交流网. 版权所有

    豫ICP备11007008号-1