为什么我们使用动态代理 [英] Why we use Dynamic Proxy
问题描述
A 描述代码中的动态代理:
公共静态类DynamicProxyGenerator
{
public static T GetInstanceFor< T>()
{
类型typeOfT = typeof(T);
var methodInfos = typeOfT.GetMethods();
AssemblyName assName = new AssemblyName(testAssembly);
var assBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assName,AssemblyBuilderAccess.RunAndSave);
var moduleBuilder = assBuilder.DefineDynamicModule(testModule,test.dll);
var typeBuilder = moduleBuilder.DefineType(typeOfT.Name +Proxy,TypeAttributes.Public);
typeBuilder.AddInterfaceImplementation(typeOfT);
var ctorBuilder = typeBuilder.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
new Type [] {});
var ilGenerator = ctorBuilder.GetILGenerator();
ilGenerator.EmitWriteLine(创建代理实例);
ilGenerator.Emit(OpCodes.Ret);
foreach(methodInfos中的var methodInfo)
{
var methodBuilder = typeBuilder.DefineMethod(
methodInfo.Name,
MethodAttributes.Public | MethodAttributes.Virtual,
methodInfo.ReturnType,
methodInfo.GetParameters()。选择(p => p.GetType())。ToArray()
);
var methodILGen = methodBuilder.GetILGenerator();
if(methodInfo.ReturnType == typeof(void))
{
methodILGen.Emit(OpCodes.Ret);
}
else
{
if(methodInfo.ReturnType.IsValueType || methodInfo.ReturnType.IsEnum)
{
MethodInfo getMethod = typeof(Activator) .GetMethod(/ span>CreateInstance,new Type [] {typeof((Type)});
LocalBuilder lb = methodILGen.DeclareLocal(methodInfo.ReturnType);
methodILGen.Emit(OpCodes.Ldtoken) ,lb.LocalType);
methodILGen.Emit(OpCodes.Call,typeofype).GetMethod(GetTypeFromHandle)); ));
methodILGen.Emit(OpCodes.Callvirt,getMethod);
methodILGen.Emit(OpCodes.Unbox_Any,lb.LocalType);
}
else
{
methodILGen.Emit(OpCodes.Ldnull);
}
methodILGen.Emit(OpCodes.Ret);
}
typeBuilder.DefineMethodOverride(methodBuilder,methodInfo);
}
类型constructType = typeBuilder.CreateType();
var instance = Activator.CreateInstance(constructType);
return(T)实例;
}
}
A dynamic proxy class is a class that implements a list of interfaces specified at runtime such that a method invocation through one of the interfaces on an instance of the class will be encoded and dispatched to another object through a uniform interface. It can be used to create a type-safe proxy object for a list of interfaces without requiring pre-generation of the proxy class.Dynamic proxy classes are useful to an application or library that needs to provide type-safe reflective dispatch of invocations on objects that present interface APIs
Above picture is good sample but Why we use dynamic proxy?
Is there any a simple example that use in real world,for more perception?
解决方案This link describe dynamic proxy in code:
public static class DynamicProxyGenerator { public static T GetInstanceFor<T>() { Type typeOfT = typeof(T); var methodInfos = typeOfT.GetMethods(); AssemblyName assName = new AssemblyName("testAssembly"); var assBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assName, AssemblyBuilderAccess.RunAndSave); var moduleBuilder = assBuilder.DefineDynamicModule("testModule", "test.dll"); var typeBuilder = moduleBuilder.DefineType(typeOfT.Name + "Proxy", TypeAttributes.Public); typeBuilder.AddInterfaceImplementation(typeOfT); var ctorBuilder = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, new Type[] { }); var ilGenerator = ctorBuilder.GetILGenerator(); ilGenerator.EmitWriteLine("Creating Proxy instance"); ilGenerator.Emit(OpCodes.Ret); foreach (var methodInfo in methodInfos) { var methodBuilder = typeBuilder.DefineMethod( methodInfo.Name, MethodAttributes.Public | MethodAttributes.Virtual, methodInfo.ReturnType, methodInfo.GetParameters().Select(p => p.GetType()).ToArray() ); var methodILGen = methodBuilder.GetILGenerator(); if (methodInfo.ReturnType == typeof(void)) { methodILGen.Emit(OpCodes.Ret); } else { if (methodInfo.ReturnType.IsValueType || methodInfo.ReturnType.IsEnum) { MethodInfo getMethod = typeof(Activator).GetMethod(/span>"CreateInstance",new Type[]{typeof((Type)}); LocalBuilder lb = methodILGen.DeclareLocal(methodInfo.ReturnType); methodILGen.Emit(OpCodes.Ldtoken, lb.LocalType); methodILGen.Emit(OpCodes.Call, typeofype).GetMethod("GetTypeFromHandle")); )); methodILGen.Emit(OpCodes.Callvirt, getMethod); methodILGen.Emit(OpCodes.Unbox_Any, lb.LocalType); } else { methodILGen.Emit(OpCodes.Ldnull); } methodILGen.Emit(OpCodes.Ret); } typeBuilder.DefineMethodOverride(methodBuilder, methodInfo); } Type constructedType = typeBuilder.CreateType(); var instance = Activator.CreateInstance(constructedType); return (T)instance; } }
这篇关于为什么我们使用动态代理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!