Dav*_*e S 36 .net c# reflection proxy
我正在尝试动态创建代理类.我知道有一些非常好的框架可以做到这一点,但这纯粹是一个宠物项目作为一个学习练习,所以我想自己做.
例如,如果我有以下类实现接口:
interface IMyInterface
{
void MyProcedure();
}
class MyClass : IMyInterface
{
void MyProcedure()
{
Console.WriteLine("Hello World");
}
}
Run Code Online (Sandbox Code Playgroud)
为了拦截这个类的方法以便记录它们,我正在创建另一个类(我的代理类版本),它实现相同的接口但包含对"真实"类的引用.此类执行操作(例如,日志记录),然后在真实类上调用相同的方法.
例如:
class ProxyClass : IMyInterface
{
private IMyInterface RealClass { get; set; }
void MyProcedure()
{
// Log the call
Console.WriteLine("Logging..");
// Call the 'real' method
RealClass.MyProcedure();
}
}
Run Code Online (Sandbox Code Playgroud)
然后调用者调用代理类上的所有方法(我使用基本的home-brew IoC容器来注入代理类来代替真正的类).我正在使用此方法,因为我希望能够RealClass
在运行时将其换出到另一个实现相同接口的类.
有没有办法ProxyClass
在运行时创建并填充其RealClass
属性,以便它可以用作真实类的代理?是否有一种简单的方法可以做到这一点,还是需要使用类似的东西Reflection.Emit
并生成MSIL?
bra*_*dmo 51
看看System.Runtime.Remoting.Proxies.RealProxy.您可以使用它从调用者的角度创建一个看似是目标类型的实例.RealProxy.Invoke提供了一个点,您可以在该点上简单地调用基础类型上的目标方法,或者在调用之前/之后执行其他处理(例如,记录).
以下是在每次方法调用之前/之后记录到控制台的代理示例:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
以下是如何使用它:
IMyInterface intf = LoggingProxy<IMyInterface>.Create(new MyClass());
intf.MyProcedure();
Run Code Online (Sandbox Code Playgroud)
然后输出到控制台将是:
在调用之前:MyProcedure
Hello World
调用之后:MyProcedure
归档时间: |
|
查看次数: |
32721 次 |
最近记录: |