经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 编程经验 » 查看文章
IOC的理解,整合AOP,解耦对Service层和Dal层的依赖
来源:cnblogs  作者:从未太晚  时间:2018/10/8 9:08:25  对本文有异议


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

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

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

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

  1. using Microsoft.Practices.Unity;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using Ruanmou.Interface;
  7. using System;
  8. using Unity.Attributes;
  9. namespace Ruanmou.Service
  10. {
  11. public class ApplePhone : IPhone
  12. {
  13. [Dependency]//属性注入:不错,但是有对容器的依赖
  14. public IMicrophone iMicrophone { get; set; }
  15. public IHeadphone iHeadphone { get; set; }
  16. public IPower iPower { get; set; }
  17. //[InjectionConstructor]
  18. public ApplePhone()
  19. {
  20. Console.WriteLine("{0}构造函数", this.GetType().Name);
  21. }
  22. //[InjectionConstructor]//构造函数注入:最好的,默认找参数最多的构造函数
  23. public ApplePhone(IHeadphone headphone)
  24. {
  25. this.iHeadphone = headphone;
  26. Console.WriteLine("{0}带参数构造函数", this.GetType().Name);
  27. }
  28. public void Call()
  29. {
  30. Console.WriteLine("{0}打电话", this.GetType().Name);
  31. }
  32. [InjectionMethod]//方法注入:最不好的,增加一个没有意义的方法,破坏封装
  33. public void Init1234(IPower power)
  34. {
  35. this.iPower = power;
  36. }
  37. }
  38. }

 

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

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

 

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

例子1

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

  1. <container name="testContainer1">
  2. <register type="Ruanmou.Interface.IPhone,Ruanmou.Interface" mapTo="Ruanmou.Service.ApplePhone, Ruanmou.Service"/>
  3. <register type="Ruanmou.Interface.IPhone,Ruanmou.Interface" mapTo="Ruanmou.Service.AndroidPhone, Ruanmou.Service" name="Android"/>
  4. <register type="Ruanmou.Interface.IMicrophone, Ruanmou.Interface" mapTo="Ruanmou.Service.Microphone, Ruanmou.Service"/>
  5. <register type="Ruanmou.Interface.IHeadphone, Ruanmou.Interface" mapTo="Ruanmou.Service.Headphone, Ruanmou.Service"/>
  6. <register type="Ruanmou.Interface.IPower, Ruanmou.Interface" mapTo="Ruanmou.Service.Power, Ruanmou.Service"/>
  7. <register type="Ruanmou.IDAL.IBaseDAL, Ruanmou.IDAL" mapTo="Ruamou.DAL.BaseDAL, Ruamou.DAL"/>
  8. </container>
  9.  
  10. <container name="testContainer">
  11. <register type="Ruanmou.Interface.IPhone,Ruanmou.Interface" mapTo="Ruanmou.Service.AndroidPhone, Ruanmou.Service.Extend"/>
  12. <register type="Ruanmou.Interface.IPhone,Ruanmou.Interface" mapTo="Ruanmou.Service.AndroidPhone, Ruanmou.Service.Extend" name="Android"/>
  13. <register type="Ruanmou.Interface.IMicrophone, Ruanmou.Interface" mapTo="Ruanmou.Service.Microphone, Ruanmou.Service.Extend"/>
  14. <register type="Ruanmou.Interface.IHeadphone, Ruanmou.Interface" mapTo="Ruanmou.Service.Headphone, Ruanmou.Service.Extend"/>
  15. <register type="Ruanmou.Interface.IPower, Ruanmou.Interface" mapTo="Ruanmou.Service.Power, Ruanmou.Service.Extend"/>
  16. <register type="Ruanmou.IDAL.IBaseDAL, Ruanmou.IDAL" mapTo="Ruamou.DAL.BaseDAL, Ruamou.DAL"/>
  17. </container>

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

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

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

例子3 实现AOP

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

配置文件配置,

  1. <container name="testContainerAOP">
  2. <extension type="Interception"/>
  3. <register type="Ruanmou.Interface.IPhone,Ruanmou.Interface" mapTo="Ruanmou.Service.AndroidPhone, Ruanmou.Service.Extend">
  4. <interceptor type="InterfaceInterceptor"/>
  5. <interceptionBehavior type="Ruanmou.Framework.AOP.AuthorizeBehavior, Ruanmou.Framework"/>
  6. <interceptionBehavior type="Ruanmou.Framework.AOP.SmsBehavior, Ruanmou.Framework"/>
  7. <interceptionBehavior type="Ruanmou.Framework.AOP.ExceptionLoggingBehavior, Ruanmou.Framework"/>
  8. <interceptionBehavior type="Ruanmou.Framework.AOP.CachingBehavior, Ruanmou.Framework"/>
  9. <interceptionBehavior type="Ruanmou.Framework.AOP.LogBeforeBehavior, Ruanmou.Framework"/>
  10. <interceptionBehavior type="Ruanmou.Framework.AOP.ParameterCheckBehavior, Ruanmou.Framework"/>
  11. <interceptionBehavior type="Ruanmou.Framework.AOP.LogAfterBehavior, Ruanmou.Framework"/>
  12. </register>
  13. <register type="Ruanmou.Interface.IPhone,Ruanmou.Interface" mapTo="Ruanmou.Service.AndroidPhone, Ruanmou.Service.Extend" name="Android"/>
  14. <register type="Ruanmou.Interface.IMicrophone, Ruanmou.Interface" mapTo="Ruanmou.Service.Microphone, Ruanmou.Service.Extend"/>
  15. <register type="Ruanmou.Interface.IHeadphone, Ruanmou.Interface" mapTo="Ruanmou.Service.Headphone, Ruanmou.Service.Extend"/>
  16. <register type="Ruanmou.Interface.IPower, Ruanmou.Interface" mapTo="Ruanmou.Service.Power, Ruanmou.Service.Extend"/>
  17. <register type="Ruanmou.IDAL.IBaseDAL, Ruanmou.IDAL" mapTo="Ruamou.DAL.BaseDAL, Ruamou.DAL">
  18. </register>
  19. </container>

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

  1. namespace Ruanmou.Framework.AOP
  2. {
  3. public class ExceptionLoggingBehavior : IInterceptionBehavior
  4. {
  5. public IEnumerable<Type> GetRequiredInterfaces()
  6. {
  7. return Type.EmptyTypes;
  8. }
  9. public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
  10. {
  11. IMethodReturn methodReturn = getNext()(input, getNext);
  12. Console.WriteLine("ExceptionLoggingBehavior");
  13. if (methodReturn.Exception == null)
  14. {
  15. Console.WriteLine("无异常");
  16. }
  17. else
  18. {
  19. Console.WriteLine($"异常:{methodReturn.Exception.Message}");
  20. }
  21. return methodReturn;
  22. }
  23. public bool WillExecute
  24. {
  25. get { return true; }
  26. }
  27. }
  28. }

 

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

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

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号