依赖倒置、反射、泛型、委托、AOP

1.什么是依赖倒置(DIP):是高层模块负责定义接口,底层模块负责实现。抽象不应该依赖于实现,实现应该依赖于抽象。抽象是个高层模块,定义好抽象,就可以对实现进行不同的实现。Human是高层模块Man的抽象,Car是底层模块Audi的抽象.不难发现高层的Man并不直接依赖底层的Audi,其两者都有各自的抽象,这就是上文提到的”高层不应该直接依赖底层,双方应该依赖抽象”

DIP是设计原则(如何依赖),控制反转IOC是设计模式(怎么做),用来实现对象之间的“解耦”,ioc有依赖注入和服务定位2种,依赖注入di,构造函数注入、属性注入、接口注入。

public class AccessDal:IDataAccess

{
        public void Add()
        {
            Console.WriteLine("在ACCESS数据库中添加一条记录!");
        }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace DIPTest
{
    class Program
    {
        static void Main(string[] args)
        {
             AccessDal dal = new AccessDal();//在外部创建依赖对象
               Order order = new Order(dal);//通过构造函数注入依赖
 
               order.Add();
 
            Console.Read();
        }
    }
}

 除了手动注入还有ioc容器的方式。

Ninject、Castle Windsor、Autofac、StructureMap、Unity、MEF、Spring.NET、LightInject

从原来的对象相互依赖,通过第三方将各个对象解耦。这个第三方就是IOC容器,起到粘合剂的作用。

 由于IOC容器的加入,对象A与对象B之间失去了直接联系,所以,当对象A运行到需要对象B的时候,IOC容器会主动创建一个对象B注入到对象A需要的地方。

IOC中最基本的技术就是“反射(Reflection)”编程

容器使用的基本套路是不变的,实例化容器,然后注册,然后使用即可。

IUnityContainer unityContainer = new UnityContainer();//实例化控制器
//实现注入
unityContainer.RegisterType<IBird, Swallow>();//IBird一个鸟类的接口,定义鸟叫的方法。//swallow对鸟类实例化,
IBird bird = unityContainer.Resolve<IBird>();

bird.Say();

接口代码:

public interface IBird
{

void Say( );

实例化代码:

  1. public class Swallow : IBird
  2.  
    {
  3.  
    public void Say( )
  4.  
    {
  5.  
    Console.WriteLine("燕子在叫...");
  6.  
    }

实现燕子在叫。

实例化另一个对象:

public class Sparrow : IBird 

public void Say()

 { Console.WriteLine("麻雀在叫...."); 

}} 

实现输出:

//实例化一个控制器
IUnityContainer unityContainer = new UnityContainer();
//实现注入
unityContainer.RegisterType<IBird, Swallow>();
unityContainer.RegisterType<IBird, Sparrow>();

IBird bird = unityContainer.Resolve<IBird>();

bird.Say();

Console.Read();
出现最后一个注入的实现。麻雀在叫...

 

//实例化一个控制器
IUnityContainer unityContainer = new UnityContainer();
//实现注入,用别名区分实现
unityContainer.RegisterType<IBird, Swallow>("Swallow");
unityContainer.RegisterType<IBird, Sparrow>("Sparrow");

IBird swallow = unityContainer.Resolve<IBird>("Swallow");
IBird sparrow = unityContainer.Resolve<IBird>("Sparrow");

swallow.Say();
sparrow.Say();

通过加上别名实现2种实例。

 

2.反射就是动态获取动态获得程序集里面的元数据,如类中的属性和方法。

程序集是啥,理解是引用的dll是程序集,早绑定就是引用程序集,然后new对象,运行时之前就加载他,进一步获取属性方法等;晚绑定即反射,先加载需要反射的dll

 

  Assembly assembly = Assembly.Load("Ruanmou.DB.Sqlserver");//1 动态加载     默认加载当前路径的dll文件,不需要后缀
   //Assembly assembly1 = Assembly.LoadFile(@"E:\online7\20160928Advanced7Course2Reflection\MyReflection\MyReflection\bin\Debug\Ruanmou.DB.Sqlserver.dll");// 必须是完整路径
  //Assembly assembly2 = Assembly.LoadFrom("Ruanmou.DB.Sqlserver.dll");// 可以是当前路径  也可以是完整路径

 Assembly asmb = Assembly.LoadFrom(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", "xxx.dll"));

反射获取dll下的类:

 foreach (var item in assembly.GetTypes())
                {
                    Console.WriteLine(item.FullName);
                }

获取方法:

foreach (varitem in typeDBHelper.GetMethods())

                {
                    Console.WriteLine(item.Name);
                }

GetProperties()获取属性,GetFields()获取字段

 SYSTEM.Type返回加载堆上的类型对象,Getmethod获取某个方法,invoke执行方法。

    //通过程序集的名称反射
    Assembly ass = Assembly.Load("ClassLibrary");
    Type t = ass.GetType("ClassLibrary.NewClass");
    object o = Activator.CreateInstance(t, "grayworm", "http://hi.baidu.com/grayworm");
    MethodInfo mi = t.GetMethod("show");
    mi.Invoke(o, null);

如:

Type t= Assembly.Load(config[x]).GetType(config[0]);
cached = Activator.CreateInstance(t) as ICache;
return cached;

 

3.泛型是啥,是个占位符,将不同类型用一个占位符表示。声明一个可以给多个类型参数共同使用的方法

//声明一个泛型方法 public void GenericMethod<T>(T tParamter) { }

//声明一个泛型接口
public interface IGenericInterface<T>
{

}

//声明一个泛型类
public class IGenericClass<T>
{

}

//声明一个泛型委托
public delegate void GenericDelegate<T>(T tParameter);
public delegate void GenericDelegate<T>();

泛型约束:

是对T的约束,基类约束、接口约束(IInterface)、引用类型约束(where T : class )、值类型(where T : struct)、无参构造函数约束(where T : new())

where T : new()只要T是否有无参构造函数,如: Tester<SomeType> t = new Tester<SomeType>();  判断SomeType是否有无参构造函数。

 

协变和逆变:使用in T作为参数,只能作为传入参不能作为返回值,父类传给子类,这是逆变。使用out T作为参数,只能作为return 的值,不能作为传入值,协变。

public interface ICustomerListIn<in T> { void Show(T t); }

public class CustomerListIn<T> : ICustomerListIn<T> { public void Show(T t) { } }逆变

public interface ICustomerListOut<out T> { T Get(); }

public class CustomerListOut<T> : ICustomerListOut<T> { public T Get() { return default(T); } }协变

 

 4. 委托:

委托都会提到事件,事件是委托的一个特例,委托是把方法作为参数,在另一个方法里面传递和调用。

//step01:首先用delegate定义一个委托 。
    public delegate int CalculatorAdd(int x, int y);
    // step02:声明一个方法来对应委托。
    public int Add(int x, int y)
    {
        return x + y;
    }
  //step03:用这个方法来实例化这个委托。
        CalculatorAdd cAdd = new CalculatorAdd(Add);
        //int result = cAdd(5, 6);
        int result = cAdd.Invoke(5,6);
匿名方法:
 public delegate int CalculatorAdd(int x, int y);
 CalculatorAdd cAdd = delegate(int x, int y) { return x + y; };
 int result = cAdd.Invoke(5, 6);
lambda:简化匿名方法
public delegate int CalculatorAdd(int x, int y);
        //方法一:
        CalculatorAdd cAdd1 = (int x, int y) => { return x + y; };
        int result1 = cAdd1(5, 6);

        //方法二:
        CalculatorAdd cAdd2 = (x, y) => { return x + y; };
        int result2 = cAdd2(5, 6);

        //方法三:
        CalculatorAdd cAdd3 = (x, y) => x + y;
        int result3 = cAdd3(5, 6);
泛型委托:一步是定义一个委托,另一步是用一个方法来实例化一个委托,用Func来简化一个委托的定义
//方法三:
        Func<int, int, int> cAdd3 = (x, y) => x + y;
        int result3 = cAdd3(5, 6);
 Action是无返回值的泛型委托; Func是有返回值的泛型委托; predicate 是返回bool型的泛型委托 ;Comparison 表示比较同一类型的两个对象的方法:public delegate int Comparison<T>(T x, T y);

委托的使用:先创建一个实例 public delegat int dint(int x,int y),定义方法 public int add(int x,int y),定义委托变量 delegate d1,关联方法 d1=add 关联多个方法d1+=add,调用委托实例d1(1,3)

5.AOP

AOP:面向切面编程,统一处理业务逻辑的一种技术。场景:日志记录,错误捕获、性能监控等。通过代理对象来间接执行真实对象,同装饰类


实现方式:动态代理和IL 编织,静态织入以Postshop为代表,而动态代理分为普通反射、Emit反射、微软提供的.Net Remoting和RealProxy。

 
posted @ 2019-08-29 16:53  lovebear  阅读(523)  评论(0编辑  收藏  举报