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. Apache NiFi 核心概念和关键特性

    本文来源于官方文档翻译 NiFi 的核心概念 NiFi 最早是美国国家安全局内部使用的工具,用来投递海量的传感器数据.后来由 apache 基金会开源.天生就具备强大的基因.NiFi基本设计理念与 F ...

  2. ASP.NET Core Web API 跨域(CORS) Cookie问题

    身为一个Web API,处理来自跨域不同源的请求,是一件十分合理的事情. 先上已有的文章,快速复制粘贴,启用CORS: Microsoft:启用 ASP.NET Core 中的跨域请求 (CORS) ...

  3. 使用 PowerShell 远程管理

    要求 PowerShell 版本要求至少是2.0版本以上,目前PowerShell 2.0 支持最低的操作系统版本为Windows XP.本次操作使用的是 PowerShell 5.1 请使用管理员身 ...

  4. Serilog 自定义Enricher 来增加记录的信息

    Serilog 自定义Enricher 来增加记录的信息 Intro Serilog 是 .net 里面非常不错的记录日志的库,结构化日志记录,而且配置起来很方便,自定义扩展也很方便 Serilog ...

  5. JWT+Interceptor实现无状态登录和鉴权

    无状态登录原理 先提一下啥是有状态登录 单台tomcat的情况下:编码的流程如下 前端提交表单里用户的输入的账号密码 后台接受,查数据库, 在数据库中找到用户的信息后,把用户的信息存放到session ...

  6. HTTP与HTTPS之面试必备

    本文主要讲解Http与https的区别,以及https是怎样加密来保证安全的. 首先讲这俩个协议的简单区别: HTTP:超文本传输协议. HTTPS:安全套接字层超文本传输协议HTTP+SSL HTT ...

  7. 本地在不安装Oracle的情况下安装PLSQL客户端

    本文解决问题:   通常在本地安装PLSQL后,如果本地没有安装Oracle数据库的话,PLSQL是不能使用的,输入远程数据库登录信息会提示:"Oracle Client没有正确安装&quo ...

  8. Elasticsearch6.x和7.x版本常用插件汇总

    elasticsearch插件汇总 基于es 7.3版本试用. 一.安全插件 1.x-pack a.介绍 包括安全(x-pack-security),监视(x-pack-watcher),警报(x-p ...

  9. Python RPC 之 gRPC

    gRPC 简介: gRPC 是一款高性能.开源的 RPC 框架,产自 Google,基于 ProtoBuf 序列化协议进行开发,支持多种语言(Golang.Python.Java等),本篇只介绍 Py ...

  10. BUPTOJj83

    83. A + B Problem 时间限制 1000 ms 内存限制 65536 KB 题目描述 Calculate the sum of two given integers A and B. 输 ...