博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
为ASP.NET MVC创建一个基于Unity的ControllerFactory
阅读量:7078 次
发布时间:2019-06-28

本文共 4864 字,大约阅读时间需要 16 分钟。

谈到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 
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
GetAllContacts();
11: }
12: 
13: public class DefaultContactRepository : IContactRepository
14: {
15:     public IEnumerable
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
2: @{
3:     ViewBag.Title = "Index";
4: }
5: 
6: 

Contact List

7: 
8: 
9: 
    10: @foreach (var contact in this.Model)
    11: {
    12:     
  • 13:         

    @contact.Name

    14:         

    Gender: @contact.Gender

    15:         

    Address: @contact.Address

    16:         

    17:     
    18: }
    19: 
    20: 

    自定义的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: 
    2:   
    3:   
    4:   
    5:     
    6:   
    7: 

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

    作者:蒋金楠
    微信公众账号:大内老A
    微博:
    如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号
    蒋金楠的自媒体将会停用)。
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    你可能感兴趣的文章
    LeetCode:Clone Graph
    查看>>
    git的合并与推送
    查看>>
    前端优化
    查看>>
    c++的检测的确比C++更严格
    查看>>
    ibatis增删改、批量增删改以及查询
    查看>>
    Installing MySQL on Microsoft Windows Using a noinstall Zip Archive
    查看>>
    今日份挨批记(2019/2/20)
    查看>>
    Hybrid App开发 四大主流移平台分析
    查看>>
    js call和apply[转]
    查看>>
    8月21日学习内容整理:range
    查看>>
    NSLog的替代品
    查看>>
    【虚拟化系列】VMware vSphere 5.1 网络管理
    查看>>
    centos远程桌面无法连接
    查看>>
    About VB
    查看>>
    移动设备(触屏设备)禁止放大缩小网页小技巧
    查看>>
    shell日期循环
    查看>>
    CopyOnWriteList-JDK1.8
    查看>>
    Python多线程一学就会!
    查看>>
    django 常用 import
    查看>>
    安卓手机APP压力monkey测试
    查看>>