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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM