1. 程式人生 > >Unity IoC Base On MVC

Unity IoC Base On MVC

生命周期 pos 分享 獨立 dll 自動 ets static ice

Unity框架,是一個經典的IoC模式實現方式,其通過config文件配置section,將接口與實現解藕,config中的section配置的container以全名稱對應,使得應用程序無需像Ninject方式那樣,依賴接口項和實現項,因其解藕的配置,能讓應用程序實現靜態更新服務的效果,即不退出應用程序更新服務的功能。

下面是Unity的實現,其核心接口IUnityContainer是Unity模式實現的基礎,在Controller生命周期中IUnityContainer起到傳遞section配置的作用,在Controller實例化時創建依賴的接口服務的實例對象,當Countroller執行結束後,接口服務的實例對象交由IUnityContainer維護

首先需要安裝Unity,引用以下兩個dll

技術分享

接下來實現Unity的管理類,新建mvc5網站項目,並如下實現

public class UnityControllerFactory : DefaultControllerFactory
    {
        static object syncHelper = new object();
        static Dictionary<string, IUnityContainer> containers = new Dictionary<string, IUnityContainer>();
        
public IUnityContainer UnityContainer { get; private set; } public UnityControllerFactory(string containerName = "") { if (containers.ContainsKey(containerName)) { this.UnityContainer = containers[containerName]; return; }
lock (syncHelper) { if (containers.ContainsKey(containerName)) { this.UnityContainer = containers[containerName]; return; } IUnityContainer container = new UnityContainer(); //配置UnityContainer UnityConfigurationSection configSection = ConfigurationManager.GetSection(UnityConfigurationSection.SectionName) as UnityConfigurationSection; if (null == configSection && !string.IsNullOrEmpty(containerName)) { throw new ConfigurationErrorsException("The <unity> configuration section does not exist."); } if (null != configSection) { if (string.IsNullOrEmpty(containerName)) { configSection.Configure(container); } else { configSection.Configure(container, containerName); } } containers.Add(containerName, container); this.UnityContainer = containers[containerName]; } } protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) { if (null == controllerType) { return null; } return (IController)this.UnityContainer.Resolve(controllerType); } public override void ReleaseController(IController controller) { this.UnityContainer.Teardown(controller); } }

假設有一個服務接口在一個獨立的C#類庫名為MyInterface

public interface IEmployeeRepository
    {
        IEnumerable<Employee> GetEmployees(string id = "");
    }

和服務接口的實現項在一個獨立的C#類庫名為MyService

public class EmployeeRepository: IEmployeeRepository
    {
        private static IList<Employee> employees;
        static EmployeeRepository()
        {
            employees = new List<Employee>();
            employees.Add(new Employee(Guid.NewGuid().ToString(), "張三", "", new DateTime(1981, 8, 24), "銷售部"));
            employees.Add(new Employee(Guid.NewGuid().ToString(), "李四", "", new DateTime(1982, 7, 10), "人事部"));
            employees.Add(new Employee(Guid.NewGuid().ToString(), "王五", "", new DateTime(1981, 9, 21), "人事部"));
        }
        public IEnumerable<Employee> GetEmployees(string id = "")
        {
            return employees.Where(e => e.Id == id || string.IsNullOrEmpty(id) || id == "*");
        }
    }

在上面新建的mvc5網站項目中,引用MyInterface的C#類庫,在網站的global文件中Application_Start中添加如下這句,將我們創建的UnityControllerFactory註入給ControllerBuilder初始化

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

在mvc5網站的web.config中添加section接口服務map信息,將接口與其服務實現類信息配置給Unity

<unity>
    <containers>
      <container>
        <register type="Mvc.IEmployeeRepository, Mvc.MvcApp" 
                  mapTo="Mvc.EmployeeRepository, Mvc.MvcApp"/>
      </container>
    </containers>
  </unity>

Unity與於Ninject的好處很明顯,接口與實現解藕,無需直接依賴實現項,達到靜態更新的效果,在應用程序運行時,只需將實現項的DLL(此處即為MyService.dll)下載替換,即可實現服務更新,要實現自動化靜態更新當然需要做些工作,比如MyService應該需要版本檢測及下載功能,有興趣的可以做做

Unity IoC Base On MVC