加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

IOC的理解,整合AOP,解耦对Service层和Dal层的依赖

发布时间:2020-12-14 05:05:28 所属栏目:百科 来源:网络整理
导读:?DIP依赖倒置原则:系统架构时,高层模块不应该依赖于低层模块,二者通过抽象来依赖 依赖抽象,而不是细节 ?贯彻依赖倒置原则,左边能抽象,右边实例化的时候不能直接用抽象,所以需要借助一个第三方 ?高层本来是依赖低层,但是可以通过工厂(容器)来决定细节


?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.Service.Extend"/>
        <register type="Ruanmou.Interface.IPhone,Ruanmou.Service.Extend" name="Android"/>
        <register type="Ruanmou.Interface.IMicrophone,Ruanmou.Service.Extend"/>
        <register type="Ruanmou.Interface.IHeadphone,Ruanmou.Service.Extend"/>
        <register type="Ruanmou.Interface.IPower,Ruanmou.Service.Extend"/>
        <register type="Ruanmou.IDAL.IBaseDAL,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.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,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垃圾回收

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读