DIP依赖倒置原则:系统架构时,高层模块不应该依赖于低层模块,二者通过抽象来依赖
依赖抽象,而不是细节

贯彻依赖倒置原则,左边能抽象,右边实例化的时候不能直接用抽象,所以需要借助一个第三方

高层本来是依赖低层,但是可以通过工厂(容器)来决定细节,去掉了对低层的依赖
 IOC控制反转:把高层对低层的依赖,转移到第三方决定,避免高层对低层的直接依赖(是一种目的)
那么程序架构就具备良好扩展性和稳定性

DI依赖注入:是用来实现IOC的一种手段,
 在构造对象时,可以自动的去初始化,对象需要的对象
构造函数注入 属性注入 方法注入,IOC容器初始化ApplePhone的时候 通过配置文件实例化 属性,方法,构造函数

using Microsoft.Practices.Unity;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ruanmou.Interface;
using System;
using Unity.Attributes; namespace Ruanmou.Service
{
public class ApplePhone : IPhone
{
[Dependency]//属性注入:不错,但是有对容器的依赖
public IMicrophone iMicrophone { get; set; }
public IHeadphone iHeadphone { get; set; }
public IPower iPower { get; set; } //[InjectionConstructor]
public ApplePhone()
{
Console.WriteLine("{0}构造函数", this.GetType().Name);
} //[InjectionConstructor]//构造函数注入:最好的,默认找参数最多的构造函数
public ApplePhone(IHeadphone headphone)
{
this.iHeadphone = headphone;
Console.WriteLine("{0}带参数构造函数", this.GetType().Name);
} public void Call()
{
Console.WriteLine("{0}打电话", this.GetType().Name);
} [InjectionMethod]//方法注入:最不好的,增加一个没有意义的方法,破坏封装
public void Init1234(IPower power)
{
this.iPower = power;
}
}
}

不管是构造对象,还是注入对象,这里都是靠反射做到的

有了依赖注入,才可能做到无限层级的依赖抽象,才能做到控制反转

IOC Unity容器 可以通过代码注册或配置文件注册接口对应实现类,实现了不依赖具体,可以对对象全局单例,线程单例

例子1

Service业务逻辑层升级,在原有1.0的基础上添加一些功能,使用配置文件注册

      <container name="testContainer1">
<register type="Ruanmou.Interface.IPhone,Ruanmou.Interface" mapTo="Ruanmou.Service.ApplePhone, Ruanmou.Service"/>
<register type="Ruanmou.Interface.IPhone,Ruanmou.Interface" mapTo="Ruanmou.Service.AndroidPhone, Ruanmou.Service" name="Android"/>
<register type="Ruanmou.Interface.IMicrophone, Ruanmou.Interface" mapTo="Ruanmou.Service.Microphone, Ruanmou.Service"/>
<register type="Ruanmou.Interface.IHeadphone, Ruanmou.Interface" mapTo="Ruanmou.Service.Headphone, Ruanmou.Service"/>
<register type="Ruanmou.Interface.IPower, Ruanmou.Interface" mapTo="Ruanmou.Service.Power, Ruanmou.Service"/>
<register type="Ruanmou.IDAL.IBaseDAL, Ruanmou.IDAL" mapTo="Ruamou.DAL.BaseDAL, Ruamou.DAL"/>
</container> <container name="testContainer">
<register type="Ruanmou.Interface.IPhone,Ruanmou.Interface" mapTo="Ruanmou.Service.AndroidPhone, Ruanmou.Service.Extend"/>
<register type="Ruanmou.Interface.IPhone,Ruanmou.Interface" mapTo="Ruanmou.Service.AndroidPhone, Ruanmou.Service.Extend" name="Android"/>
<register type="Ruanmou.Interface.IMicrophone, Ruanmou.Interface" mapTo="Ruanmou.Service.Microphone, Ruanmou.Service.Extend"/>
<register type="Ruanmou.Interface.IHeadphone, Ruanmou.Interface" mapTo="Ruanmou.Service.Headphone, Ruanmou.Service.Extend"/>
<register type="Ruanmou.Interface.IPower, Ruanmou.Interface" mapTo="Ruanmou.Service.Power, Ruanmou.Service.Extend"/>
<register type="Ruanmou.IDAL.IBaseDAL, Ruanmou.IDAL" mapTo="Ruamou.DAL.BaseDAL, Ruamou.DAL"/>
</container>

只需要把服务2.0的类库(实现1.0的原有接口)dll拿过来即可使用,代码不做任何修改

例子2 业务扩展,新加功能

应该是加几个接口和实现类的映射,就可以解决了。

例子3 实现AOP

方法需要加日志,加异常管理,可以不修改原有代码,直接新加异常管理类等的类库,在Unity配置文件添加AOP配置节点即可实现

配置文件配置,

      <container name="testContainerAOP">
<extension type="Interception"/>
<register type="Ruanmou.Interface.IPhone,Ruanmou.Interface" mapTo="Ruanmou.Service.AndroidPhone, Ruanmou.Service.Extend">
<interceptor type="InterfaceInterceptor"/>
<interceptionBehavior type="Ruanmou.Framework.AOP.AuthorizeBehavior, Ruanmou.Framework"/>
<interceptionBehavior type="Ruanmou.Framework.AOP.SmsBehavior, Ruanmou.Framework"/>
<interceptionBehavior type="Ruanmou.Framework.AOP.ExceptionLoggingBehavior, Ruanmou.Framework"/>
<interceptionBehavior type="Ruanmou.Framework.AOP.CachingBehavior, Ruanmou.Framework"/>
<interceptionBehavior type="Ruanmou.Framework.AOP.LogBeforeBehavior, Ruanmou.Framework"/>
<interceptionBehavior type="Ruanmou.Framework.AOP.ParameterCheckBehavior, Ruanmou.Framework"/>
<interceptionBehavior type="Ruanmou.Framework.AOP.LogAfterBehavior, Ruanmou.Framework"/>
</register>
<register type="Ruanmou.Interface.IPhone,Ruanmou.Interface" mapTo="Ruanmou.Service.AndroidPhone, Ruanmou.Service.Extend" name="Android"/>
<register type="Ruanmou.Interface.IMicrophone, Ruanmou.Interface" mapTo="Ruanmou.Service.Microphone, Ruanmou.Service.Extend"/>
<register type="Ruanmou.Interface.IHeadphone, Ruanmou.Interface" mapTo="Ruanmou.Service.Headphone, Ruanmou.Service.Extend"/>
<register type="Ruanmou.Interface.IPower, Ruanmou.Interface" mapTo="Ruanmou.Service.Power, Ruanmou.Service.Extend"/>
<register type="Ruanmou.IDAL.IBaseDAL, Ruanmou.IDAL" mapTo="Ruamou.DAL.BaseDAL, Ruamou.DAL">
</register>
</container>

贴一个异常处理的AOP例子代码

namespace Ruanmou.Framework.AOP
{
public class ExceptionLoggingBehavior : IInterceptionBehavior
{
public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
} public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
IMethodReturn methodReturn = getNext()(input, getNext); Console.WriteLine("ExceptionLoggingBehavior");
if (methodReturn.Exception == null)
{
Console.WriteLine("无异常");
}
else
{
Console.WriteLine($"异常:{methodReturn.Exception.Message}");
}
return methodReturn;
} public bool WillExecute
{
get { return true; }
}
}
}

例子4 数据访问层的替换,因为已经不依赖具体实现,把配置文件的接口对应的数据访问层实现类替换即可,配置文件格式为InterFace Map 实现类

数据访问层的封装公共增删改查,Unity 管理 EF DBcontext,保持全局或线程单例还没有看到,最近在学内存管理和.Net垃圾回收

IOC的理解,整合AOP,解耦对Service层和Dal层的依赖的更多相关文章

  1. asp.net mvc 简单项目框架的搭建过程(一)对Bll层和Dal层进行充分解耦

    学习asp.net 已经有近三个月的时间了,在asp.net mvc上花的时间最多,但个人真是有些菜,不得不说,asp.net mvc的水真的还是蛮深的.目前在公司实习,也见过公司几个项目的代码了.对 ...

  2. ioc初步理解(一) 简单实用autofac搭建mvc三层+ioc(codeFirst)

    1]首先搭好框架 1.1]搭建ui层 1.2]创建其他内库文件 整个项目基本部分搭建完毕之后如下 2]使用nuget引用文件 先在每一个项目中引入ef 然后再UI层引入以下两个文件autofac和Au ...

  3. SSM框架中IoC、DI与AOP的理解

    框架封装了普通项目中程序员需要重复书写的代码和调用过程,就比如说在传统的jsp项目中,我们的controller接收到前端的请求然后程序员就需要去开发Dao层,里面还涉及数据库的连接和存储过程的代码, ...

  4. AOP和IOC个人理解

    14:18 2014/5/5 IOC inversion of control 控制反转  将new对象的权力由调用者转移到spring容器(即xml文件),Struts2与Spring整合(scop ...

  5. 初步理解IOC和DI和AOP模式

    初步理解IOC和DI和AOP模式 控制反转(IOC) 控制反转(IOC,Inversion of Control)是一种转主动为被动关系的一种编程模式,有点类似于工厂模式,举个栗子, 下面这个这不是I ...

  6. 对IOC和DI以及AOP的理解

    为了理解Spring的IoC与DI从网上查了很多资料,作为初学者,下面的描述应该是最详细,最易理解的方式了. 首先想说说IoC(Inversion of Control,控制倒转).这是spring的 ...

  7. IOC和DI,AOP的本质理解

    IOC: Inversion of Control,控制反转, 控制权从应用程序转移到框架(如IOC容器),是框架共有的特性. 对于IOC的理解,可以把IOC看作是一个生产和管理bean对象的容器.原 ...

  8. Spring Boot2(六):使用Spring Boot整合AOP面向切面编程

    一.前言 众所周知,spring最核心的两个功能是aop和ioc,即面向切面和控制反转.本文会讲一讲SpringBoot如何使用AOP实现面向切面的过程原理. 二.何为aop ​ aop全称Aspec ...

  9. Spring中IOC的理解

    Spring中IOC的理解 1.什么是IOC? (1)控制反转.把对象创建和对象间的调用过程交给Spring进行管理. (2)使用IOC的目的:为了耦合度降低. 2.IOC底层原理? (1)xml解析 ...

随机推荐

  1. [LeetCode] New 21 Game 新二十一点游戏

    Alice plays the following game, loosely based on the card game "21". Alice starts with 0 p ...

  2. su;su -;sudo;sudo -i;sudo su;sudo su - 之间的区别

    今天我们来聊聊su;su -;sudo;sudo -i;sudo su;sudo su -他们之间的区别. su :su 在不加任何参数,默认为切换到root用户,但没有转到root用户家目录下,也就 ...

  3. 关于如何在Visual Studio上仿真调试安卓的U3D应用

    正巧最近需要开发一个安卓手机上的Unity3D游戏功能,想着既然要开发么,当然需要调试.本来的话一些基础功能是不需要使用仿真模拟器,直接在U3D的开发编辑器上就能调试,不过有一些安卓上才能执行,比如 ...

  4. [error] eclipse编写spring等xml配置文件时只有部分提示,tx无提示

    eclipse编写spring等xml配置文件时只有<bean>.<context>等有提示,其他标签都没有提示 这时就需要做以下两步操作(下面以事务管理标签为例) 1,添加命 ...

  5. Spring源码工程导入Eclsipse缺少两个jar文件

    按照<Spring源码深度解析>所述,使用gradle cleanidea eclipse将Spring源码转为eclipse工程后,导入eclipse,最后发现还是缺少spring-cg ...

  6. linux系统中的时间

    1.编程显示系统时间: #include <stdio.h> #include <time.h> /* gcc -o fix fixedFormatTime.c ./fix * ...

  7. JMeter 测试 ActiveMq

    JMeter 测试 ActiveMq 的资料非常少, 我花了大量的时间才研究出来 关于ActiveMq 的文章请参考我另外的文章. 阅读目录 版本号: ActiveMq 版本号:  5.91 Jmet ...

  8. 【RL-TCPnet网络教程】第18章 BSD Sockets基础知识

    第18章      BSD Sockets基础知识 本章节为大家讲解BSD Sockets,需要大家对BSD Sockets有个基础的认识,方便后面章节Socket实战操作. (本章的知识点主要整理自 ...

  9. Angularjs中的缓存以及缓存清理

    写在最前面:这篇博文是2篇文章组成,详细介绍了Angularjs中的缓存以及缓存清理,文章由上海尚学堂转载过来,欢迎大家阅读和评论.转载请注明出处,谢谢! 一个缓存就是一个组件,它可以透明地储存数据, ...

  10. PCD文件格式详解及在PCL下读取PCD文件

    一.PCD简介 1.1 PCD版本 在点云库PCL 1.0发布之前,PCD文件格式就已经发展更新了许多版本.这些新旧不同的版本用PCD_Vx来编号(例如PCD_V5.PCD_V6和PCD_V7等),分 ...