• Ioc依赖注入:Unity4.0.1 在项目中的应用 (MVC和API)


    使用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

     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

  • 相关阅读:
    JS Array转JSON
    js数组转字符串并用,分割
    java枚举类-根据key获取value及根据value获取key
    CSS文件引入顺序
    git pull之前要先commit
    FastJson中@JSONField注解使用
    @JsonFormat与@DateTimeFormat注解的使用
    Jackson 时间格式化,时间注解 @JsonFormat 用法、时差问题说明
    shell脚本使用
    ubuntu12.04 安装redis
  • 原文地址:https://www.cnblogs.com/peterzhang123/p/12108733.html
Copyright © 2020-2023  润新知