Unity IOC注入詳細配置(MVC,WebApi)


一直想寫一篇關於unity 詳細的配置信息的文章,也算是自我總結吧

先介紹了unity , Unity是微軟官方推薦使用的輕型的IOC框架,支持各種方式的注入 ,使用來解耦的利器.

獲取unity 的方式呢你可以直接下載對應的dll文件或者去對應的網站下載,我個人推薦呢用NuGet直接添加和管理.

添加方式如下圖

 

 

安裝之后呢會自動添加到項目里,當有更新的時候,直接在窗口里面更新就行,或者執行命令行 Update-Package  Mvc{tab}

,如果你只需要注入普通的MVC的話那現在啊就可以了。但是如果你可能還需要注入webapi的話那么你就還需要引入這個庫

磨刀不誤砍柴工,包准備好了現在可以開始配置了,

總的來說unity的配置分為3步

1:填寫配置文件指定映射關系

2:創建容器載入配置文件

3:構造注入或者屬性注入。

完成了這幾步呢就可以開始使用了

 

先說配置文件吧。先發個圖看看完整的結構

其實看這很負責用起來的話不是這樣,如果你只是簡單來用的話其實就只需要關注5個節點

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
  </configSections>
  <unity>

    
    
    <alias alias="IClass" type="IservicesVc.test, IservicesVc" />
    <alias alias="MyClass" type="Services.test, Services" />
    
    <namespace name="IservicesVc.test" />
    <namespace name="Services.test" />
    
    <assembly name="IservicesVc" />
    <assembly name="Services" />    
    <container>
   
      <register type="Itesttwo" mapTo="testtwo" />
      <register type="ITestIoc" mapTo="TestIo" />
    </container>
  </unity>
</configuration>

從上往下看呢首先<alias>節點用來指定程序集之間的映射關系 alias是表示節點的別名,type是指定類型用的 "結構為命名空間+文件名,命名空間",,<namespace>用來指定引用程序集的命名空間 name屬性=命名空間+文件夾名稱(如果是多個映射),<assembly > name="程序命名空間" 用來指定引用的程序集

<container> 就是容器節點了。里面的<register>節點用來用的類之間的映射關系,type="需要映射的類型",mapto="映射的目標類型" 下面貼下對應的代碼

namespace IservicesVc.test
{
    public interface ITestIoc
    {
        int sum(int sumone, int sumtwo);

    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IservicesVc.test
{
    public interface Itesttwo
    {
        int count(int i, int j);
    }
}
using IservicesVc.test;

namespace Services.test
{
    public class TestIo :ITestIoc
    {
      public  int sum(int sumone, int sumtwo)
      {
          return sumone + sumtwo;

      }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IservicesVc.test;
using Microsoft.Practices.Unity;

namespace Services.test
{
 public   class testtwo:Itesttwo

    
    {
     [Dependency]
     public ITestIoc ii { get; set; }
     public int count(int i, int j)
     {
         var sum = ii.sum(i,j);
         return sum * sum;

     }
    }
}

配置完成后呢。就是需要開始注冊了。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using TestUnityIocVC.App_Start;

namespace TestUnityIocVC
{
    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            GlobalConfiguration.Configure(WebApiConfig.Register);

            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            //注入方法
            Bootstrapper.Initialise();
        }
    }
}

重點是Bootstrapper.Initialise();方法

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using IservicesVc.test;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using Services.test;
using Unity.WebApi;

namespace TestUnityIocVC.App_Start
{
    public static class Bootstrapper
    {
        public static void Initialise()
        {
            //UnityContainer container = new UnityContainer();
            //UnityConfigurationSection configuration = ConfigurationManager.GetSection(UnityConfigurationSection.SectionName) as UnityConfigurationSection;
            //configuration.Configure(container, "defaultContainer");  
            var container = BuildUnityContainer();
            DependencyResolver.SetResolver(new UnityDependencyResolver(container));//MVC注入
        
           //GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);//MVC
            GlobalConfiguration.Configuration.DependencyResolver = new  Unity.WebApi.UnityDependencyResolver(container);//WebAPi注入
        }


        /// <summary>
        /// Builds the unity container.
        /// </summary>
        /// <returns></returns>
        private static IUnityContainer BuildUnityContainer()
        {
            var container = new UnityContainer();
            //container.RegisterType<INodeBiz, NodeBiz>();
            var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = HttpContext.Current.Server.MapPath("~/Unity.config") };
            Configuration configuration =
                ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
            var unitySection = (UnityConfigurationSection)configuration.GetSection("unity");
            container.LoadConfiguration(unitySection);
            //container.RegisterType<ITestIoc, TestIo>();
            return container;
        }
    }
}

通過BuildUnityContainer方法構造容器, 容器的結構是從配置文件的讀取的,但是現在你如果運行會報錯為什么呢,因為你如果需要MVC注入的話還需要一些別的處理.

我們要實現MVC3中新提供 的兩個接口:IDependencyResolver和IControllerActivator

IDependencyResolver公開兩個方法 - GetService的GetServices.The GetService方法解決了單獨注冊的服務,支持任意對象的創建,GetServices解決注冊多個服務。IDependencyResolver接口的實現應該委托給底層的依賴注入容器提供注冊服務請求的類型。當有沒有注冊的服務請求的類型,ASP.NET MVC框架預計這個接口的實現返回GetService為空,並從GetServices返回空集合。讓我們以統一提供依賴注入工作IDependencyResolver intreface派生創建一個自定義的依賴解析器類。

我們定義一個類名為UnityDependencyResolver:

using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Microsoft.Practices.Unity;

namespace TestUnityIocVC
{
    public class UnityDependencyResolver : IDependencyResolver
    {
        IUnityContainer container;
        public UnityDependencyResolver(IUnityContainer container)
        {
            this.container = container;
        }

        public object GetService(Type serviceType)
        {
            try
            {
                return container.Resolve(serviceType);
            }
            catch
            {
                return null;
            }
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            try
            {
                return container.ResolveAll(serviceType);
            }
            catch
            {
                return new List<object>();
            }
        }
    }
}

實現兩個方法GetService和GetServices。使用Unity容器返回我們需要的Service或者ojbect。

實現兩個方法GetService和GetServices。使用Unity容器返回我們需要的Service或者ojbect。

ASP.NET MVC 3以后的版本已經推出了一個新的接口IControllerActivator,讓您激活與自定義的行為控制器,並且可以使用依賴注入.讓我們創建一個派生自IControllerActivator 接口的一個自定義的控制器

Icontroller

using System;
using System.Web.Mvc;

namespace TestUnityIocVC
{
    public class CustomControllerActivator : IControllerActivator
    {
        IController IControllerActivator.Create(System.Web.Routing.RequestContext requestContext,
            Type controllerType)
        {
            return DependencyResolver.Current
                .GetService(controllerType) as IController;
        }
    }
}

到這。整個注冊就完成了

那么在MVC 的控制器和webapi中就可以用了

(MVC)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using IservicesVc;
using IservicesVc.test;
using Microsoft.Practices.Unity;
using Services.test;

namespace TestUnityIocVC.Controllers
{
    public class HomeController : Controller
    {

        //屬性注入;
        [Dependency]
        public ITestIoc _TestIoc { get; set; }


        public Itesttwo test = DependencyResolver.Current.GetService<Itesttwo>();
        //private readonly ITestIoc _testIoc;

        //public HomeController(ITestIoc testIoc)
        //{
        //    _testIoc = testIoc;
        //}

        public ActionResult Index()
        {
            var count = _TestIoc.sum(10, 20);
            ViewBag.Title = "home";

            return View();
        }
    }
}

(WEBapi)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using IservicesVc.test;

namespace TestUnityIocVC.Controllers.Api
{
    public class testController : ApiController
    {
        private readonly Itesttwo _testIoc;
        public testController(Itesttwo testIoc)
        {
            _testIoc = testIoc;

        }

        public IEnumerable<string> Get()
        {
            var sum = _testIoc.count(10, 20);
            return new string[] { "value1", sum.ToString() };
        }
    }
}

。好了到這整個流程就算是結束了。這是本人第一次寫博客。有些用語不合適或者描述的不清楚的地方請諒解。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM