IOC的理解,整合AOP,解耦對Service層和Dal層的依賴


 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;
        }
    }
}

 

無論是構造對象,仍是注入對象,這裏都是靠反射作到的函數

有了依賴注入,纔可能作到無限層級的依賴抽象,才能作到控制反轉ui

 

IOC Unity容器 能夠經過代碼註冊或配置文件註冊接口對應實現類,實現了不依賴具體,能夠對對象全局單例,線程單例this

例子1spa

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 業務擴展,新加功能code

應該是加幾個接口和實現類的映射,就能夠解決了。對象

例子3 實現AOPblog

方法須要加日誌,加異常管理,能夠不修改原有代碼,直接新加異常管理類等的類庫,在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垃圾回收

相關文章
相關標籤/搜索