简介
依赖注入主要是一种结构性的模式, 注重的是类与类之间的结构, 它要达到的目的就是设计原则中最少知道和合成复用的原则, 减少内部依赖, 履行单一职责, 最终就是强解耦. 依赖注入目前最好的实现就是依赖注入容器.
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);
- }
运行测试结果达到工厂模式同样的效果, 并且可扩展性更强, 项目解耦, 减少项目依赖.
至此, 项目介绍完毕, 更多精彩, 且听下回分解!
来源: https://www.cnblogs.com/henxiao25/p/11497782.html