使用 Unity 的好处网上有很多, 百度一下即可
这里引用了一篇关于面向接口编程的好处的文章作为引申: https://blog.csdn.net/Cyy19970527/article/details/83177996
在 MVC 中使用 Unity
需要引用 Unity 包, 我安装的版本为 Unity-4.0.1
尽管现在 Unity 最新版本已经更新到 5.11.2 了, 但是在使用配置文件注入的时候, 总是报以下错误,
百度查找到一篇文章说是版本问题: https://blog.csdn.net/weixin_34124577/article/details/93533679
接下来直接上测试代码: 项目结构使用简单的三层结构
DAL 层
- 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 层
- 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
- /// <summary>
- /// 用于自动实现对象类
- /// </summary>
- 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>();
- }
- }
- }
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
来源: http://www.bubuko.com/infodetail-3357573.html