Ioc依賴注入:Unity4.0.1 在項目中的應用 (MVC和API)

使用Unity的好處網上有不少,百度一下便可html

這裏引用了一篇關於面向接口編程的好處的文章做爲引伸:https://blog.csdn.net/Cyy19970527/article/details/83177996編程

在MVC中使用Unityapp

須要引用Unity包,我安裝的版本爲 Unity-4.0.1ide

儘管如今Unity最新版本已經更新到5.11.2了,可是在使用配置文件注入的時候,老是報如下錯誤,函數

百度查找到一篇文章說是版本問題: https://blog.csdn.net/weixin_34124577/article/details/93533679測試

接下來直接上測試代碼:項目結構使用簡單的三層結構this

DAL層spa

namespace DAL
{
    //聲明一個接口層,獲取名稱
    public interface IADao
    {
        string GetName();
    }
}

//實現1
public class A1Dao : IADao
{
    public string GetName()
    {
        return "我叫A1";
    }
}


//實現2
public class A2Dao : IADao
{
    public string GetName()
    {
        return "我叫A2";
    }
}

BLL層.net

namespace BLL
{
    //聲明一個Bll層接口
    public interface IA
    {
        string GetName();
    }
}

//實現1
public class A1 : IA
{
    IADao _a1;

    //構造函數注入
    [InjectionConstructor]
    public A1(IADao a1)
    {
        _a1 = a1;
    }

    public string GetName()
    {
        return _a1.GetName();
    }
}

//實現2
public class A2 : IA
{
    //屬性注入 "a2dao" 是區分兩個不一樣實現的標識,在配置文件中聲明該名稱
    [Dependency("a2dao")]
    public DAL.IADao _a1 { get; set; }

    public string GetName()
    {
        return _a1.GetName();
    }
}

在控制器中調用插件

public class HomeController : Controller
{
    //經過屬性注入
    [Dependency("a2")]
    public IA _a2 { get; set; }


    private IA _ia;
    
//構造函數注入 [InjectionConstructor]
public HomeController(IA ia) //若是都經過構造函數注入,則經過該方式區分([Dependency("a1")]IA a1,[Dependency("a2")]IA a2) { _ia = ia; } public ActionResult Index() { ViewBag.Name = _ia.GetName(); //經過構造函數注入獲取 ViewBag.A2Name = _a2.GetName(); //經過屬性注入獲取 return View(); } }

顯示結果:

接下來講如何配置

1,首先要引用Unity插件

2,而後在App_Start 文件夾下建立一個註冊配置類UnityConfig (引用插件的時候會自動建立,自定義也能夠),用來註冊配置文件Unity.config中的配置,

   /// <summary>
    /// 配置文件公用類
    /// </summary>
    public class UnityConfig
    {
        /// <summary>
        /// MVC注入  在全局方法中調用該方法,實現全局註冊
        /// </summary>
        public static void Start()
        {
            var container = ApiContainer.GetUnityContainer();
            RegisterTypes(container);

            DependencyResolver.SetResolver(new UnityDependencyResolver(container));   //MVC注入
        }

        /// <summary>
        /// 使用配置文件註冊
        /// </summary>
        /// <param name="container"></param>
        private static void RegisterTypes(IUnityContainer container)
        {
            //使用單獨的Unity.config配置文件
            var filepath = HttpRuntime.AppDomainAppPath;
            var context = HttpContext.Current;
            if (context != null)
            {
                filepath = context.Server.MapPath("~/");
            }
            var getfile = filepath + "Unity.config";
            var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = getfile };
            Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
            var unitySection = (UnityConfigurationSection)configuration.GetSection("unity");
            container.LoadConfiguration(unitySection, "defaultContainer");

            //在App.config或者Web.Config中配置
            //UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
            //container.LoadConfiguration(section, "defaultContainer");  //或者section.Configure(container, "defaultContainer");
        }
    }

 3,而後一樣在App_Start 文件夾下建立一個UnityDependencyResolver 類,同時實現接口:IDependencyResolver

 1 /// <summary>
 2 /// 用於自動實現對象類
 3 /// </summary>
 4 public class UnityDependencyResolver : IDependencyResolver
 5 {
 6     IUnityContainer container;
 7     public UnityDependencyResolver(IUnityContainer container)
 8     {
 9         this.container = container;
10     }
11 
12     public object GetService(Type serviceType)
13     {
14         try
15         {
16             return container.Resolve(serviceType);
17         }
18         catch
19         {
20             return null;
21         }
22     }
23 
24     public IEnumerable<object> GetServices(Type serviceType)
25     {
26         try
27         {
28             return container.ResolveAll(serviceType);
29         }
30         catch
31         {
32             return new List<object>();
33         }
34     }
35 }

4,寫一個Unity公共類,也能夠將該類集成到項目中

    /// <summary>
    /// Unity公共類
    /// </summary>
    public class ApiContainer
    {
        private readonly static IUnityContainer _container = null;

        /// <summary>
        /// 初始化容器
        /// </summary>
        /// <returns></returns>
        static ApiContainer()
        {
            //新建容器構建器,用於註冊組件和服務
            _container = new UnityContainer();
        }

        /// <summary>
        /// 對外開放函數 獲取Unity容器
        /// </summary>
        /// <returns></returns>
        public static IUnityContainer GetUnityContainer()
        {
            return _container;
        }

        /// <summary>
        /// 獲取實例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T GetServer<T>()
        {
            return _container.Resolve<T>();
        }

        /// <summary>
        /// 能夠根據ConfigName獲取實例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ConfigName">配置文件中指定的文字</param>
        /// <returns></returns>
        public static T GetServer<T>(string ConfigName)
        {
            return _container.Resolve<T>(ConfigName);
        }

        /// <summary>
        /// 返回構結函數帶參數
        /// </summary>
        /// <typeparam name="T">依賴對象</typeparam>
        /// <param name="ConfigName">配置文件中指定的文字(沒寫會報異常)</param>
        /// <param name="parameterList">參數集合(參數名,參數值)</param>
        /// <returns></returns>
        public static T GetServer<T>(Dictionary<string, object> parameterList)
        {
            var list = new ParameterOverrides();
            foreach (KeyValuePair<string, object> item in parameterList)
            {
                list.Add(item.Key, item.Value);
            }
            return _container.Resolve<T>(list.OnType<T>());
        }


    }

5,在項目根目錄下建立一個 Unity.config 文件,配置以下

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>
  </configSections>
  <unity>
    <containers>
      <container name="defaultContainer">
        <register type="BLL.IA,BLL" mapTo="BLL.A1, BLL"/>
        <register type="BLL.IA,BLL" mapTo="BLL.A2, BLL"  name="a2" />
        <register type="DAL.IADao,DAL" mapTo="DAL.A1Dao, DAL"/>
        <register type="DAL.IADao,DAL" mapTo="DAL.A2Dao, DAL" name="a2dao"/>
      </container>
    </containers>
  </unity>
</configuration>

6,在全局中註冊 Global.asax.cs

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        UnityConfig.Start(); //全局註冊   可經過構造函數or屬性調用
    }
}

到此所有結束

若是要在 WebAPI中使用Unity,則除了引用Unity插件,還要引用 Unity.WebApI 插件,引用版本以下:

而後須要調整一處地方,將MVC的注入方式換成WebAPI的注入方式,以下:

using System;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.WebApi;
using System.Web.Http;
namespace API.App_Start { /// <summary> /// 配置文件公用類 /// </summary> public class UnityConfig { public static void Start() {
//DependencyResolver.SetResolver(new UnityDependencyResolver(container));   //MVC注入方式
GlobalConfiguration.Configuration.DependencyResolver
= new UnityDependencyResolver(GetConfiguredContainer()); //API注入方式 }
} }

 另外須要去掉上邊代碼中的 UnityDependencyResolver : IDependencyResolver 實現。API的不須要實現以下接口, 去掉以下圖的實現。

 

其餘的地方都同樣。

 

參考文章:

https://www.cnblogs.com/qqlin/archive/2012/10/18/2720828.html

https://blog.csdn.net/hezheqiang/article/details/80255280

相關文章
相關標籤/搜索