关于C#的动态代理实现原理

所谓动态代理,就是不直接访问目标对象,而是通过反射生成一个目标代理类,由中间代理对象来代理目标对象的方法,常见的一些AOP框架Aspect.Core | Castle | DispatchProxy 也都是基于DynamicAssembly实现的,动态生成代理类,通过 Emit 创建要生成动态代理类的方法/属性...

实现动态代理如下:

代理类实际创建过程:

internal class ProxyUtil
{
    private const string ProxyAssemblyName = "Aop.DynamicGenerated";
    private static readonly ModuleBuilder _moduleBuilder;
    private static readonly ConcurrentDictionary<string, Type> _proxyTypes = new ConcurrentDictionary<string, Type>();

    static ProxyUtil()
    {
        // 定义一个动态程序集
        var asmBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(ProxyAssemblyName), AssemblyBuilderAccess.Run);
        // 创建一个动态模块,后面创建动态代理类通过这个来创建
        _moduleBuilder = asmBuilder.DefineDynamicModule("Default");
    }

    public static Type CreateInterfaceProxy(Type interfaceType)
    {
        var proxyTypeName = $"{ProxyAssemblyName}.{interfaceType.FullName}";
        var type = _proxyTypes.GetOrAdd(proxyTypeName, name =>
        {
            // 定义要创建的类型,并实现指定类型接口
            var typeBuilder = _moduleBuilder.DefineType(proxyTypeName, TypeAttributes.Public, typeof(object), new[] { interfaceType });
            // 定义一个默认的构造方法
            typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
            // 获取接口中定义的方法
            var methods = interfaceType.GetMethods(BindingFlags.Instance | BindingFlags.Public);
            foreach (var method in methods)
            {
                // 在动态类中定义方法,方法名称,返回值和签名与接口方法保持一致
                var methodBuilder = typeBuilder.DefineMethod(method.Name
                    , MethodAttributes.Public | MethodAttributes.Virtual,
                    method.CallingConvention,
                    method.ReturnType,
                    method.GetParameters()
                        .Select(p => p.ParameterType)
                        .ToArray()
                    );                

                // 获取 ILGenerator,通过 Emit 实现方法体
                var ilGenerator = methodBuilder.GetILGenerator();
                ilGenerator.EmitWriteLine($"method [{method.Name}] is invoking...");
                ilGenerator.Emit(OpCodes.Ret);
                
                // 定义方法实现
                typeBuilder.DefineMethodOverride(methodBuilder, method);
            }

            return typeBuilder.CreateType();
        });
        return type;
    }
}

代理类的创建:

public class ProxyGenerator
{
    public static readonly ProxyGenerator Instance = new ProxyGenerator();

    public object CreateInterfaceProxy(Type interfaceType)
    {
        var type = ProxyUtil.CreateInterfaceProxy(interfaceType);
        return Activator.CreateInstance(type);
    }
}
// 定义泛型扩展
public static class ProxyGeneratorExtensions
{
    public static TInterface CreateInterfaceProxy<TInterface>(this ProxyGenerator proxyGenerator) =>
        (TInterface)proxyGenerator.CreateInterfaceProxy(typeof(TInterface));
}

使用:

var testService = ProxyGenerator.Instance.CreateInterfaceProxy<ITestService>();
testService.Test();

AOP就是在创建的代理类中某个方法前后执行某个逻辑

posted @ 2021-01-07 13:48  Yeah的第七章  阅读(1171)  评论(1编辑  收藏  举报