关于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就是在创建的代理类中某个方法前后执行某个逻辑