- 简介
依赖注入主要是一种结构性的模式,注重的是类与类之间的结构,它要达到的目的就是设计原则中最少知道和合成复用的原则,减少内部依赖,履行单一职责,最终就是强解耦。依赖注入目前最好的实现就是依赖注入容器。
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); }
运行测试结果达到工厂模式同样的效果,并且可扩展性更强、项目解耦,减少项目依赖。
至此,项目介绍完毕,更多精彩,且听下回分解!
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。如有问题,可以邮件:896374871@qq.com QQ:896374871 联系我,非常感谢。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!