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);
}

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

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

基于.net EF6 MVC5+WEB Api 的Web系统框架总结(3)-项目依赖注入的更多相关文章

  1. Web API(六):使用Autofac实现依赖注入

    在这一篇文章将会讲解如何在Web API2中使用Autofac实现依赖注入. 一.创建实体类库 1.创建单独实体类 创建DI.Entity类库,用来存放所有的实体类,新建用户实体类,其结构如下: us ...

  2. http服务 WCF、Web API、Web service、WCF REST之间的区别

      http服务 WCF.Web API.Web service.WCF REST之间的区别 在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web ...

  3. NET Web API和Web API Client Gen使Angular 2应用程序

    使用ASP.NET Web API和Web API Client Gen使Angular 2应用程序的开发更加高效 本文介绍“ 为ASP.NET Web API生成TypeScript客户端API ” ...

  4. Web API和Web Service

    首先,Web API是由Web Service演变而来,它们两者关系就是所有Web Service都是API,但并非所有API都是Web Service.其次,两者都有利于信息的传输,但Web API ...

  5. Web APi之Web Host消息处理管道(六)

    前言 我们知道Web API本身是无法提供请求-响应的机制,它是通过Web Host以及Self Host的寄宿的宿主方式来提供一个请求-响应的运行环境.二者都是将请求和响应抽象成HttpRespon ...

  6. 返璞归真 asp.net mvc (11) - asp.net mvc 4.0 新特性之自宿主 Web API, 在 WebForm 中提供 Web API, 通过 Web API 上传文件, .net 4.5 带来的更方便的异步操作

    原文:返璞归真 asp.net mvc (11) - asp.net mvc 4.0 新特性之自宿主 Web API, 在 WebForm 中提供 Web API, 通过 Web API 上传文件, ...

  7. ASP.NET MVC , ASP.NET Web API 的路由系统与 ASP.NET 的路由系统是怎么衔接的?

      ASP.NET MVC 的路由实际上是建立在 ASP.NET 的路由系统之上的. MVC 路由注册通常是这样的: RouteTable 是一个全局路由表, 它的 Routes 静态属性是一个 Ro ...

  8. 基于.net EF6 MVC5+WEB Api 的Web系统框架总结(1)-Web前端页面

    本 Web 系统框架基于C# EF6+MVC+WebApi的快速应用开发平台.本节主要介绍Web前端页面设计与实现.Web前端页面主要分为普通列表页面.树状导航列表页面.普通编辑页面.数据导入页面.向 ...

  9. 基于.net EF6 MVC5+WEB Api 的Web系统框架总结(2)-业务项目搭建

    本节将介绍如何进行业务项目搭建. 本业务项目示例是简单的企业信息管理功能,业务项目采用Code First方式,搭建包括: 创建实体项目 创建实体数据表映射 创建业务处理项目 创建业务Web项目 搭建 ...

随机推荐

  1. java学习笔记(中级篇)—java实现高质量图片压缩

    使用java几十行代码实现一个高质量图片压缩程序,再也不用去自己找网络的压缩程序啦!而且很多网上的工具还有水印或者其他的限制,自己动手写一个简单的应用,是再合适不过了. 一.实现原理 1.声明两个字符 ...

  2. Jmeter 接口测试参数处理

    问题: 一.签名参数sign算法由文字描述,算法需自己编写 二. 参数param_json为变化的json串(json串内订单号唯一) 解决: 一. 签名sign: 1. 手动拼接后在https:// ...

  3. java虚拟机学习笔记(五)---运行时的数据区域

    Java虚拟机所管理的内存包括以下几个运行时的数据区域:方法区,堆,虚拟机栈,本地方法栈,程序计数器.下面对其进行介绍: 程序计数器 它是一块较小的内存空间,可以看做当前线程做执行的字节码的信号指示器 ...

  4. 如何搭建环境---初识mybatis

    一:mybatis概念1:简介       MyBatis本是apache的一个开源项目iBatis,2010年改名为 MyBatis,       MyBatis 是一个基于Java的持久层框架.( ...

  5. C语言tips_1 关于&& || ! 的优先级

    关于&& || ! 三种操作的优先级 测试如下 简要分析 假设&&>|| 则结果为1 假设||>&& 则结果为0 结果为1 得证 & ...

  6. 99% 的人都不知道的 Kubernetes 网络疑难杂症排查方法

    原文链接:Kubernetes 网络疑难杂症排查分享 大家好,我是 roc,来自腾讯云容器服务 (TKE) 团队,经常帮助用户解决各种 K8S 的疑难杂症,积累了比较丰富的经验,本文分享几个比较复杂的 ...

  7. linux安装MySQL后输入mysql显示 ERROR 2002 (HY000): Can't connect to local MySQL server through socket

    我是小白,大佬勿喷 *** linux安装MySQL后输入mysql显示 ERROR 2002 (HY000): Can't connect to local MySQL server through ...

  8. 析构函数中调用 Dispose 报错 :Internal .Net Framework Data Provider error 1.[非原创]

    搜索MSDN的资源可以找到答案: 原文如下http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=473449&SiteID=1 以下是关于 ...

  9. jmeter之beanshell使用

    beanshell官网:http://www.BeanShell.org/ 一.beanshell介绍 是一种完全符合Java语法规范的轻量级的脚本语言: 相当于一个小巧免费嵌入式的Java源代码解释 ...

  10. tomcat启动nio,apr详解以及配置

    tomcat启动nio,apr详解以及配置 前言 在正文开始之前,我们先在idea工具中看看启动的信息,顺便看下启动的基本信息 在这里插入图片描述可以看到信息有tomcat版本操作系统版本java版本 ...