IOC与DI+面向切面编程AOP

IOC与DI

1 IOC控制反转和DI依赖注入

1.1 定义及作用

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

贯彻依赖倒置原则,左边能抽象,右边实例化的时候不能直接用抽象,所以需要借助第三方
高层本来是依赖低层,但是可以通过工厂(容器)来决定细节,去掉对低层的依赖。

IOC(Inversion of Control)控制反转:把高层对低层的依赖,转移到第三方决定,避免高层的直接依赖,那么程序架构就具备良好的扩展性和稳定性

DI(Dependency Injection) 依赖注入:是用来实现IOC的一种手段
在构造对象时,可以自动化的取初始化,对象需要的其他对象(构造函数注入、属性注入、方法注入)
不管是什么注入,都是通过反射来实现的

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

1.2 分层的意义

分层是必须的
为什么分层:
1、职责清晰,方便分工合作
2、代码复用
3、体积小、方便维护

2 Unity的使用

2.1 安装

  1. install-package Unity
  2. install-package Unity.Interception
  3. install-package Unity.Interception.Configuration

2.2 Unity容器初步运用

//1、声明一个容器
IUnityContainer container = new UnityContainer();
//2、初始化容器,注册类型
container.RegisterType<IPhone, AndroidPhone>();

//3、创建对象,通过反射实现
IPhone phone = container.Resolve<IPhone>();
phone.Call();

2.3 Unity多种注册,一对多的注册

//1、声明一个容器
IUnityContainer container = new UnityContainer();
//2、初始化容器,注册类型
container.RegisterType<IPhone, AndroidPhone>();//接口


container.RegisterType<ApplePad, ApplePadChild>();//父子类

//container.RegisterType<AbstractPad, ApplePad>();//抽象类和子类
//container.RegisterType<AbstractPad, ApplePadChild>();//会覆盖 要想不被覆盖 传入形参


container.RegisterType<AbstractPad, ApplePad>("child");//抽象类和子类  一对多
container.RegisterType<AbstractPad, ApplePadChild>("GrandChild");

container.RegisterInstance<ITV>(new AppleTV(123));//注册实例,不常用(因为依赖细节了)

//3、创建对象,通过反射实现
IPhone phone = container.Resolve<IPhone>();
phone.Call();

//AbstractPad pad = container.Resolve<AbstractPad>();
ApplePad applePad = container.Resolve<ApplePad>();

AbstractPad childPad = container.Resolve<AbstractPad>("child");
childPad.Show();
AbstractPad GrandChildPad = container.Resolve<AbstractPad>("GrandChild");
childPad.Show();
ITV iTV = container.Resolve<ITV>();
iTV.Show();

2.4 Unity依赖注入,多层架构

1、声明一个容器
IUnityContainer container = new UnityContainer();
//2、初始化容器,注册类型
container.RegisterType<IPhone, ApplePhone>();
container.RegisterType<IMicrophone, Microphone>();
container.RegisterType<IPower, Power>();
container.RegisterType<IHeadphone, Headphone>();

//3、创建对象,通过反射实现
IPhone phone = container.Resolve<IPhone>();
phone.Call();


2.5 Unity生命周期管理

//容器成了创建对象的入口,可以加入自己的管理逻辑:生命周期
//1、声明一个容器
IUnityContainer container = new UnityContainer();
//2、初始化容器,注册类型
//container.RegisterType<IPhone, AndroidPhone>();//默认 瞬时

//container.RegisterType<IPhone, AndroidPhone>(new TransientLifetimeManager());//瞬时  每一次都是全新生成

// container.RegisterType<IPhone, AndroidPhone>(new ContainerControlledLifetimeManager());//容器单例  单例就是不要自己实现


//3、创建对象,通过反射实现
//IPhone phone1 = container.Resolve<IPhone>();
//IPhone phone2 = container.Resolve<IPhone>();
//Console.WriteLine(object.ReferenceEquals(phone1, phone2));
//phone1.Call();

#region 线程单例
//线程单例,相同线程的实例相同,不同线程的实例不同,  如web请求/多线程操作
container.RegisterType<IPhone, AndroidPhone>(new PerThreadLifetimeManager());//线程单例  同一个线程就是单例的   不同线程就是不同的
IPhone phone1 = null;
Action action1 = new Action(() =>
{
    phone1 = container.Resolve<IPhone>();
    Console.WriteLine($"iphone1由线程ID={Thread.CurrentThread.ManagedThreadId}");
});
var result1 = action1.BeginInvoke(null, null);

IPhone phone2 = null;
Action action2 = new Action(() =>
{
    phone2 = container.Resolve<IPhone>();
    Console.WriteLine($"iphone2由线程ID={Thread.CurrentThread.ManagedThreadId}");
});


IPhone phone3 = null;
var result2 = action2.BeginInvoke(t =>
{
    phone3 = container.Resolve<IPhone>();
    Console.WriteLine($"iphone3由线程ID={Thread.CurrentThread.ManagedThreadId}");
    Console.WriteLine($"object.ReferenceEquals(phone2, phone3) = {object.ReferenceEquals(phone2, phone3)}");
}, null);

action1.EndInvoke(result1);
action2.EndInvoke(result2);

Console.WriteLine($"object.ReferenceEquals(phone1, phone2) = {object.ReferenceEquals(phone1, phone2)}");
#endregion


//container.RegisterType<IPhone, AndroidPhone>(new HierarchicalLifetimeManager());//分级容器单例
//IUnityContainer unityContainer = container.CreateChildContainer();//获取子容器

//container.RegisterType<IPhone, AndroidPhone>(new ExternallyControlledLifetimeManager());//外部可释放单例
//container.RegisterType<IPhone, AndroidPhone>(new PerResolveLifetimeManager());//循环引用  不推荐


3 AOP面向切面编程

<!--<?xml version="1.0" encoding="utf-8" ?>-->
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
  </configSections>
  <unity>
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/>
    <containers>
      <container name="testContainer">
        <extension type="Interception"/>
        <register type="面向切面编程.UnityWay.IUserProcessor,面向切面编程" mapTo="面向切面编程.UnityWay.UserProcessor, 面向切面编程">
          <interceptor type="InterfaceInterceptor"/>
          <interceptionBehavior type="面向切面编程.UnityWay.ExceptionLoggingBehavior,面向切面编程"/>
          <interceptionBehavior type="面向切面编程.UnityWay.CachingBehavior,面向切面编程"/>
          <interceptionBehavior type="面向切面编程.UnityWay.LogBeforeBehavior,面向切面编程"/>
          <interceptionBehavior type="面向切面编程.UnityWay.ParameterCheckBehavior,面向切面编程"/>
          <interceptionBehavior type="面向切面编程.UnityWay.LogAfterBehavior,面向切面编程"/>
        </register>
      </container>
    </containers>
  </unity>
  
</configuration>
public class ParameterCheckBehavior : IInterceptionBehavior
    {
        public bool WillExecute
        {
            get
            {
                //throw new NotImplementedException();
                return true;
            }
        }

        public IEnumerable<Type> GetRequiredInterfaces()
        {
            //throw new NotImplementedException();
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            //throw new NotImplementedException();
            Console.WriteLine("ParameterCheckBehavior");
            User user = input.Inputs[0] as User;//可以不写死,反射+特性完成对数据的有效性检测
            if (user.Pwd.Length<5)
            {
                //返回一个异常
                return input.CreateExceptionMethodReturn(new Exception("密码长度不能小于10"));
            }
            else
            {
               return getNext().Invoke(input, getNext);
            }
        }
    }
 public class CachingBehavior : IInterceptionBehavior
    {
        private static Dictionary<string, object> CachingDictionary = new Dictionary<string, object>();

        public bool WillExecute
        {
            get
            {
                //throw new NotImplementedException();
                return true;
            }
        }

        public IEnumerable<Type> GetRequiredInterfaces()
        {
            //throw new NotImplementedException();
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            //throw new NotImplementedException();
            Console.WriteLine("CachingBehavior");
            string key = $"{input.MethodBase.Name}_{Newtonsoft.Json.JsonConvert.SerializeObject(input.Inputs)}";
            if (CachingDictionary.ContainsKey(key))
            {
                return input.CreateMethodReturn(CachingDictionary[key]);//相当于短路器  ,直接返回
            }
            else
            {
                IMethodReturn methodReturn = getNext().Invoke(input, getNext);
                if (methodReturn.ReturnValue!=null)
                {
                    CachingDictionary.Add(key, methodReturn.ReturnValue);
                }
                return methodReturn;
            }
        }
    }
 public class ExceptionLoggingBehavior : IInterceptionBehavior
    {
        public bool WillExecute
        {
            get
            {
                //throw new NotImplementedException();
                return true;
            }
        }

        public IEnumerable<Type> GetRequiredInterfaces()
        {
            //throw new NotImplementedException();
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            //throw new NotImplementedException();
            IMethodReturn methodReturn = getNext().Invoke(input, getNext);
            Console.WriteLine("ExceptionLoggingBehavior");
            if (methodReturn.Exception==null)
            {
                Console.WriteLine("无异常");
            }
            else
            {
                Console.WriteLine($"异常:{methodReturn.Exception.Message}");
            }
            return methodReturn;
        }
    }
public class LogAfterBehavior : IInterceptionBehavior
    {
        public bool WillExecute
        {
            get
            {
                return true;
                //throw new NotImplementedException();
            }
        }

        public IEnumerable<Type> GetRequiredInterfaces()
        {
            //throw new NotImplementedException();
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            //throw new NotImplementedException();
            IMethodReturn methodReturn  = getNext().Invoke(input, getNext);
            Console.WriteLine("LogAfterBehavior");
            Console.WriteLine(input.MethodBase.Name);//获取方法名称
            foreach (var item in input.Inputs)
            {
                Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item));
            }
            Console.WriteLine($"返回值:{methodReturn.ReturnValue}");
            return methodReturn;
        }

    }
public class LogBeforeBehavior : IInterceptionBehavior
    {
        public bool WillExecute
        {
            get
            {
                return true;
                //throw new NotImplementedException();
            }
        }

        public IEnumerable<Type> GetRequiredInterfaces()
        {
            // throw new NotImplementedException();
            return Type.EmptyTypes;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            // throw new NotImplementedException();
            Console.WriteLine("LogBeforeBehavior");

            //input拿到所有参数信息
            foreach (var item in input.Inputs)
            {
                //反射或者序列化显示更多信息//install-package Newtonsoft.Json
                Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(item));//install-package Newtonsoft.Json
            }
            //
            return getNext()(input, getNext);//getNext()得到委托实例;
        }
    }
 public class UnityConfigAOP
    {
        public static void Show()
        {
            User user = new User() { Name = "Admin", Pwd = "123" };

            {
                //通过反射创建对象
                IUnityContainer container = new UnityContainer();
                container.RegisterType<IUserProcessor, UserProcessor>();
                IUserProcessor processor = container.Resolve<IUserProcessor>();
                processor.RegUser(user);
            }

            {
                IUnityContainer container = new UnityContainer();
                ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
                fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CfgFiles\\Unity.config");
                Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

                UnityConfigurationSection unityConfigurationSection = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
                unityConfigurationSection.Configure(container, "testContainer");

                IUserProcessor processor = container.Resolve<IUserProcessor>();
                processor.RegUser(user);
            }

        }
    }

    public interface IUserProcessor
    {
        void RegUser(User user);
    }

    public class UserProcessor : IUserProcessor
    {
        public void RegUser(User user)
        {
            Console.WriteLine($"用户已注册,用户名称={user.Name} Password={user.Pwd}");
        }
    }

    public class User
    {
        public string Name { get; set; }
        public string Pwd { get; set; }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值