• 基于IoC的ControllerFactory


    IoC:

    所谓控制反转,简单的说,就是应用本身不负责依赖对象的创建和维护,而交给一个外部容器来负责,这样控制权就由应用转移到了外部IoC容器,控制权实现了所谓的反转。
    例如:在类型A中要使用类型B的实例,而B的实例创建并不是由A来负责,而是通过外部容器来创建,通过IoC的方式实现针对目标Controller的激活具有重要意义。

    Controller与Model 分离
    ASP.NET MVC 所谓的Model仅仅表示绑定到View 上的数据,我们一般称之为ViewModel,而真正意义上的Model一般指维护应用状态和提供业务功能操作的领域模型,或者针对业务层的入口或者业务服务的代理

    基于IoC的ControllerFactory
    主要是通过IoC容器对目标Controller的激活
    由于ControllerFactory包括了对Controller类型的解析、Controller实例的创建与释放及会话状态行为选项的获取。
    一般来说Controller实例的创建才需要IoC容器的控制,为了避免重新实现其他功能,这里直接继承DefaultControllerFactory,重写Controller实例的创建
    Demo:创建基于Unity的ControllerFactory
    新建一项目:

    using System;
    using System.Web.Mvc;
    using Microsoft.Practices.Unity;
    
    namespace MvcApplication3.Unity
    {
        public class UnityControllerFactory:DefaultControllerFactory
        {
            public IUnityContainer UnityContainer { get; private set; }
    
            public UnityControllerFactory(IUnityContainer unityContainer)
            {
                this.UnityContainer = unityContainer;
            }
    
            protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
            {
                if (null==controllerType)
                {
                    return null;
                }
                return (IController)this.UnityContainer.Resolve(controllerType);
            }
        }
    }
    Employee
        public class Employee
        {
            public string Id { get; private set; }
            public string Name { get; private set; }
            public string Gender { get; private set; }
            public DateTime BirthDate { get; private set; }
            public string Department { get; private set; }
    
            public Employee(string id, string name, string gender, DateTime birthdate, string department)
            {
                this.Id = id;
                this.Name = name;
                this.Gender = gender;
                this.BirthDate = birthdate;
                this.Department = department;
                
            }
        }

    创建一个EmployeeRepository对象来进行数据获取,并为它定义了对应的接口IEmployeeRepository

        public interface IEmployeeRepository
        {
            IEnumerable<Employee> GetEmployees(string id = "");
        }
    EmployeeRepository
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using MvcApplication3.IModels;
    using MvcApplication3.ViewModel;
    
    namespace MvcApplication3.Model
    {
        public class EmployeeRepository:IEmployeeRepository
        {
            public static IList<Employee> employees;
    
            static EmployeeRepository()
            {
                employees = new List<Employee>();
                employees.Add(new Employee("001","张三","",new DateTime(2011,5,10),"销售部"));
                employees.Add(new Employee("002","李四","",new DateTime(1987,4,2),"技术部"));
                employees.Add(new Employee("003","王五","",new DateTime(1932,3,6),"财务部"));
                employees.Add(new Employee("004","赵六","",new DateTime(1988,5,3),"人事部"));
                employees.Add(new Employee("005","老八","",new DateTime(1990,6,5),"销售部"));
            }
    
            public IEnumerable<Employee> GetEmployees(string id = "")
            {
                return employees.Where(e => e.Id == id || string.IsNullOrEmpty(id));
            }
        }
    }

    创建一个EmployeeController,它具有一个类型为IEmployeeRepository的属性Repository,应用Dependency特性,告诉我们这是一个“依赖属性”,当我们采用UnityContainer来激活EmployeeController对象的时候,会根据注册的类型映射来实例化一个实现了IEmployeeRepository的类型的实例来初始化该属性

    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using Microsoft.Practices.Unity;
    using MvcApplication3.IModels;
    using MvcApplication3.ViewModel;
    
    namespace MvcApplication3.Controllers
    {
        public class EmployeeController : Controller
        {
            [Dependency]
            public IEmployeeRepository Repository { get; set; }
    
            public ActionResult GetAllEmployees()
            {
                var employees = this.Repository.GetEmployees();
    
                return View("EmployeeList", employees);
            }
    
            public ActionResult GetEmployeeById(string id)
            {
                Employee employee = this.Repository.GetEmployees(id).FirstOrDefault();
                if (null==employee)
                {
                    throw new HttpException(404, string.Format("ID为{0}的员工不存在", id));
                }
                return View("EmployeeDetail", employee);
    
            }
    
        }
    }

    两个页面的代码:

    EmployeeDetail.cshtml
    @model MvcApplication3.ViewModel.Employee
    <html>
        <head>
            <title>
                @Model.Name
            </title>
            
        </head>
        <body>
            <table>
                <tr>
                    <td>
                        @Html.LabelFor(m=>m.Id)
                    </td>
                    <td>
                        @Html.DisplayFor(m=>m.Id)
                    </td>
                </tr>
                <tr>
                    <td>
                        @Html.LabelFor(m=>m.Name)
                    </td>
                    <td>
                        @Html.DisplayFor(m=>m.Name)
                    </td>
                </tr>
                <tr>
                    <td>
                        @Html.LabelFor(m=>m.Gender)
                    </td>
                    <td>
                        @Html.DisplayFor(m=>m.Gender)
                    </td>
                </tr>
                <tr>
                    <td>
                        @Html.LabelFor(m=>m.BirthDate)
                    </td>
                    <td>
                        @Html.DisplayFor(m=>m.BirthDate)
                    </td>
                </tr>
                <tr>
                    <td>
                        @Html.LabelFor(m=>m.Department)
                    </td>
                    <td>
                        @Html.DisplayFor(m=>m.Department)
                    </td>
                </tr>
            </table>
        </body>
    </html>
    EmployeeList.cshtml
    @model IEnumerable<MvcApplication3.ViewModel.Employee>
    
    <html>
    <head>
        <title>员工列表
        </title>
    </head>
    <body>
        <table>
            <tr>
                <th>姓名</th>
                <th>性别</th>
                <th>出生日期</th>
                <th>部门</th>
            </tr>
    
            @{
                foreach (MvcApplication3.ViewModel.Employee e in Model)
                {
                <tr>
                    <td>
                        @Html.ActionLink(e.Name, "GetEmployeeById", new { name = e.Name, e.Id })
                    </td>
                    <td>
                        @Html.DisplayFor(em => e.Gender)
                    </td>
                    <td>
                        @Html.DisplayFor(em => e.BirthDate)
                    </td>
                    <td>
                        @Html.DisplayFor(em => e.Department)
                    </td>
                </tr>
                }
            }
        </table>
    </body>
    </html>

    路由注册:

    RouteConfig
        public class RouteConfig
        {
            public static void RegisterRoutes(RouteCollection routes)
            {
                routes.MapRoute(
                    name: "Home",
                    url: "",
                    defaults: new { controller = "Employee", action = "GetAllEmployees", id = UrlParameter.Optional }
                );
                routes.MapRoute(
                    name: "Detail",
                    url: "{name}/{id}",
                    defaults: new { controller = "Employee", action = "GetEmployeeById" }
                    );
            }
        }

    注册接口与实现接口的类型映射:

                UnityContainer unityContainer = new UnityContainer();
                unityContainer.RegisterType<IEmployeeRepository, EmployeeRepository>();
                UnityControllerFactory controllerFactory = new UnityControllerFactory(unityContainer);
                ControllerBuilder.Current.SetControllerFactory(controllerFactory);

    结果展示:

  • 相关阅读:
    MySQL 安装
    MySQL简介
    图解十大经典的机器学习算法
    基于Python预测股价
    10_通过httprequest获取跟请求相关的信息
    07_参数提交时action的写法
    08_ServletConfig介绍
    05_servlet生命周期介绍
    06_url_pattern三种写法
    03_servletHello完成
  • 原文地址:https://www.cnblogs.com/hailiang2013/p/2882993.html
Copyright © 2020-2023  润新知