• 基于.net EF6 MVC5+WEB Api 的Web系统框架总结(3)-项目依赖注入


    1. 简介

      依赖注入主要是一种结构性的模式,注重的是类与类之间的结构,它要达到的目的就是设计原则中最少知道和合成复用的原则,减少内部依赖,履行单一职责,最终就是强解耦。依赖注入目前最好的实现就是依赖注入容器。

      Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(Dependency Injection)容器,它支持常用的三种依赖注入方式:构造器注入(Constructor Injection)、属性注入(Property Injection),以及方法调用注入(Method Call Injection).

      本项目基于Unity,减少内部依赖,实现项目解耦。基于LGPL协议开源。

     

      2.项目源码

    using Microsoft.Practices.Unity;
    using Microsoft.Practices.Unity.Configuration;
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Linq;
    using System.Text;
    
    namespace ShiQuan.Unity
    {
        /// <summary>
        /// Unity 辅助对象
        /// </summary>
        public class UnityHelper
        {
            #region 单例
    
            private static readonly UnityHelper _instance = new UnityHelper();
            /// <summary>
            /// Unity 辅助对象
            /// </summary>
            public static UnityHelper Instance
            {
                get
                {
                    return _instance;
                }
            }
            #endregion
    
            private readonly IUnityContainer _container = new UnityContainer();
            /// <summary>
            /// 获取容器
            /// </summary>
            public IUnityContainer Container
            {
                get { return _container; }
            }
            private UnityHelper()
            {
                var configuration = ConfigurationManager.GetSection(UnityConfigurationSection.SectionName) as UnityConfigurationSection;
                if (configuration != null)
                {
                    configuration.Configure(_container);
                }
            }
    
            #region 获取对应接口的具体实现类
            /// <summary>
            /// 获取实现类(默认映射)
            /// </summary>
            /// <typeparam name="T">接口类型</typeparam>
            /// <returns>接口</returns>
            public T GetResolve<T>()
            {
                return _container.Resolve<T>();
            }
            /// <summary>
            /// 获取实现类(默认映射)带参数的
            /// </summary>
            /// <typeparam name="T">接口类型</typeparam>
            /// <param name="parameter">参数</param>
            /// <returns>接口</returns>
            public T GetResolve<T>(params ParameterOverride[] parameter)
            {
                return _container.Resolve<T>(parameter);
            }
            /// <summary>
            /// 获取实现类(指定映射)带参数的
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="name"></param>
            /// <param name="parameter"></param>
            /// <returns>接口</returns>
            public T GetResolve<T>(string name, params ParameterOverride[] parameter)
            {
                return _container.Resolve<T>(name, parameter);
            }
            #endregion
    
            #region 判断接口是否被注册了
            /// <summary>
            /// 判断接口是否被实现了
            /// </summary>
            /// <typeparam name="T">接口类型</typeparam>
            /// <returns>bool</returns>
            public bool IsRegistered<T>()
            {
                return _container.IsRegistered<T>();
            }
            /// <summary>
            /// 判断接口是否被实现了
            /// </summary>
            /// <typeparam name="T">接口类型</typeparam>
            /// <param name="name">映射名称</param>
            /// <returns></returns>
            public bool IsRegistered<T>(string name)
            {
                return _container.IsRegistered<T>(name);
            }
            #endregion
        }
    }

      源码地址:https://gitee.com/ShiQuan25/ShiQuan.Unity

      3.调用示例

      下面演示调用此程序示例:

      首先我们创建数据操作基础项目,定义IDataBase接口,定义一获取名称的方法。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ShiQuan.DataAccess
    {
        /// <summary>
        /// 定义接口
        /// </summary>
        public interface IDatabase
        {
            string Name { get; }
        }
    }

           创建SQLSERVER项目,定义SqlDataBase实现IDatabase接口。

    using ShiQuan.DataAccess;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ShiQuan.DataServer
    {
        /// <summary>
        /// 实现
        /// </summary>
        public class SqlDataBase : IDatabase
        {
            public string Name
            {
                get { return "SqlDataBase"; }
            }
        }
    }

      创建MySql 项目,定义MySqlDataBase实现IDatabase接口。

    using ShiQuan.DataAccess;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ShiQuan.DataMySql
    {
        /// <summary>
        /// 实现
        /// </summary>
        public class MySqlDataBase : IDatabase
        {
            public string Name
            {
                get { return "MySqlDataBase"; }
            }
        }
    }

      创建数据操作工厂项目,定义DataFactory实现根据参数调用不同的实现类。

    using ShiQuan.DataAccess;
    using ShiQuan.DataMySql;
    using ShiQuan.DataServer;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ShiQuan.DataRepository
    {
        /// <summary>
        /// 数据工厂
        /// </summary>
        public class DataFactory
        {
            /// <summary>
            /// 获取数据操作对象
            /// </summary>
            /// <param name="name"></param>
            /// <returns></returns>
            public static IDatabase GetDataBase(string name)
            {
                switch (name)
                {
                    case "MySql":
                        {
                            return new MySqlDataBase();
                        }
                    case "SqlServer":
                    default:
                        {
                            return new SqlDataBase();
                        }
                }
                
            }
        }
    }

      创建Console程序进行测试

    using ShiQuan.DataServer;
    using ShiQuan.DataMySql;
    using ShiQuan.Unity;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using ShiQuan.DataAccess;
    using ShiQuan.DataRepository;
    
    namespace ConsoleApp
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("实例并调用Sql Server...");
                IDatabase sqlserver = DataFactory.GetDataBase("SqlServer");
                Console.WriteLine(sqlserver.Name);
    
                Console.WriteLine("实例并调用MySql...");
                IDatabase mysql = DataFactory.GetDataBase("MySql");
                Console.WriteLine(mysql.Name);
    
                Console.ReadLine();
            }
            
        }
    }

      项目结构大概是这样的:

      运行结果:

      4.Unity调用

      假设此时,如果我们需要实现其他数据库操作,实现IDatabase接口时,除了增加其他数据库操作项目,还得修改、调整数据操作工厂项目。

      但是如果我们的数据操作工厂项目改用依赖注入的方式,工厂项目是不需要引用SQLSERVER项目、MySQL项目及其他数据库操作项目,可以不改动工厂项目的情况下,主程序直接在配置文件中添加相应的操作项目及类,以达到面向接口开发、减少内部依赖、实现项目解耦。

      项目添加程序包

     

      主程序配置文件(App.Config或Web.Config)增加配置

    <configSections>
        <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration" />
      </configSections>

      配置接口,接口实现对象

     

    <unity>
        <typeAliases>
          <typeAlias alias="IDatabase" type="ShiQuan.DataAccess.IDatabase,ShiQuan.DataAccess" />
          <typeAlias alias="SqlServer" type="ShiQuan.DataServer.SqlDataBase,ShiQuan.DataServer" />
          <typeAlias alias="MySql" type="ShiQuan.DataMySql.MySqlDataBase,ShiQuan.DataMySql" />
        </typeAliases>
        <containers>
          <container>
            <type type="IDatabase" mapTo="SqlServer" name="SqlServer"></type >
            <type type="IDatabase" mapTo="MySql" name="MySql"></type >
          </container>
        </containers>
      </unity>

      工厂项目实例调用

     

    /// <summary>
            /// 获取数据操作对象
            /// </summary>
            /// <param name="name"></param>
            /// <returns></returns>
            public static IDatabase GetDataBase(string name)
            {
                //switch (name)
                //{
                //    case "MySql":
                //        {
                //            return new MySqlDataBase();
                //        }
                //    case "SqlServer":
                //    default:
                //        {
                //            return new SqlDataBase();
                //        }
                //}
                return ShiQuan.Unity.UnityHelper.Instance.GetResolve<IDatabase>(name);
            }

      运行测试结果达到工厂模式同样的效果,并且可扩展性更强、项目解耦,减少项目依赖。

     

      至此,项目介绍完毕,更多精彩,且听下回分解!

  • 相关阅读:
    Spring2.5.6学习笔记DI的两种注入方式
    hsqldb2.2.9文档学习笔记之使用hsqldb
    Spring2.5.6学习笔记实例化bean的几种方法
    eclipse4.2插件开发之Hello!EclipsePlugin
    spring boot redis 多数据源配置 spring boot data redis
    docker安装mysql
    docker安装rabbitmq
    docker命令积累
    mysql8 免安装版 下载安装
    docker安装nginx
  • 原文地址:https://www.cnblogs.com/henxiao25/p/11497782.html
Copyright © 2020-2023  润新知