动态创建一个代理类 [英] Dynamically creating a proxy class
问题描述
我想动态创建一个代理类。我知道有一些很不错的框架,在那里要做到这一点,但是这纯粹是一个宠物项目作为一个学习锻炼,想自己做。
I am trying to create a proxy class dynamically. I know there are some very good frameworks out there to do this but this is purely a pet project as a learning exercise so would like to do it myself.
如果,例如,我有以下类实现一个接口:
If, for example, I have the following class implementing an interface:
interface IMyInterface
{
void MyProcedure();
}
Class MyClass : IMyInterface
{
void MyProcedure()
{
Console.WriteLine("Hello World");
}
}
要拦截的方法来这个类,以记录他们,我创造另一个类(我的版本的代理类),它实现了相同的接口,但包含一个引用真正的类。该类执行操作(如日志记录),然后调用真正的类相同的方法。
To intercept methods to this class in order to log them, I am creating another class (my version of a proxy class) which implements the same interface but contains a reference to the 'real' class. This class performs an action (e.g. logging) and then calls the same method on the real class.
例如:
Class ProxyClass : IMyInterface
{
private IMyInterface RealClass { get; set; }
void MyProcedure()
{
// Log the call
Console.WriteLine("Logging..");
// Call the 'real' method
RealClass.MyProcedure();
}
}
呼叫者然后调用代理类的所有方法,而不是(我使用的是基本的家庭酿造IoC容器的代理类来代替真正的类的注入)。我使用这种方法,因为我希望能够换出 RealClass
在运行时另一个类实现相同的接口。
The caller then calls all methods on the proxy class instead (I am using a basic home-brew IoC container to inject the proxy class in place of the real class). I am using this method because I would like to be able to swap out RealClass
at run time to another class implementing the same interface.
有没有一种方法来创建 ProxyClass
在运行时,填充它的 RealClass
属性,因此它可以作为对于真正的类代理?有没有一种简单的方法来做到这一点还是我需要使用类似 Reflection.Emit的
并生成MSIL?
Is there a way to create ProxyClass
at run time and populate its RealClass
property so it can be used as a proxy for the real class? Is there a simple way to do this or do I need to use something like Reflection.Emit
and generate the MSIL?
推荐答案
看一看<一href="http://msdn.microsoft.com/en-us/library/system.runtime.remoting.proxies.realproxy.aspx">System.Runtime.Remoting.Proxies.RealProxy.您可以使用它来创建,似乎是从调用者的角度来看,目标类型的实例。 RealProxy.Invoke提供了一个点,您可以简单地调用底层的类型目标的方法或呼叫前/后执行额外的处理(日志等)。
Have a look at System.Runtime.Remoting.Proxies.RealProxy. You can use this to create an instance that appears to be the target type from the perspective of the caller. RealProxy.Invoke provides a point from which you can simply invoke the target method on the underlying type or perform additional processing before/after the call (logging, for example).
下面是一个代理,登录到控制台的例子前/每个方法调用后:
Here's an example of a proxy that logs to the console before/after each method invocation:
public class LoggingProxy<T> : RealProxy
{
private readonly T _instance;
private LoggingProxy(T instance)
: base(typeof(T))
{
_instance = instance;
}
public static T Create(T instance)
{
return (T)new LoggingProxy<T>(instance).GetTransparentProxy();
}
public override IMessage Invoke(IMessage msg)
{
var methodCall = (IMethodCallMessage)msg;
var method = (MethodInfo)methodCall.MethodBase;
try
{
Console.WriteLine("Before invoke: " + method.Name);
var result = method.Invoke(_instance, methodCall.InArgs);
Console.WriteLine("After invoke: " + method.Name);
return new ReturnMessage(result, null, 0, methodCall.LogicalCallContext, methodCall);
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e);
if (e is TargetInvocationException && e.InnerException != null)
{
return new ReturnMessage(e.InnerException, msg as IMethodCallMessage);
}
return new ReturnMessage(e, msg as IMethodCallMessage);
}
}
}
下面是你将如何使用它:
Here is how you would use it:
IMyInterface intf = LoggingProxy<IMyInterface>.Create(new MyClass());
intf.MyProcedure();
输出到控制台随后将是:
The output to console would then be:
调用之前:MyProcedure
你好世界维基
之后调用:MyProcedure
Before invoke: MyProcedure
Hello World
After invoke: MyProcedure
这篇关于动态创建一个代理类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!