zoukankan      html  css  js  c++  java
  • .Net学习之IOC,AOP


     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垃圾回收

  • 相关阅读:
    Typescript+WebGL+Webpack开发环境搭建
    SVG的动态之美-搜狗地铁图重构散记
    2017年个人总结-程序员的中年焦虑症
    上海2017QCon个人分享总结
    CSS预编译与PostCSS以及Webpack构建CSS综合方案
    前端工程师的基本素养
    不仅仅是复制粘贴
    《微信小程序七日谈》- 第七天:不要捡了芝麻丢了西瓜
    《微信小程序七日谈》- 第六天:小程序devtool隐藏的秘密
    《微信小程序七日谈》- 第五天:你可能要在登录功能上花费大力气
  • 原文地址:https://www.cnblogs.com/kongsq/p/9751716.html
Copyright © 2011-2022 走看看