c# - 动态创建代理类

标签 c# .net reflection proxy

我正在尝试动态创建一个代理类。我知道有一些非常好的框架可以做到这一点,但这纯粹是一个宠物项目,作为一种学习练习,所以我想自己做。

例如,如果我有以下实现接口(interface)的类:

interface IMyInterface
{
    void MyProcedure();
}

class MyClass : IMyInterface
{
    void MyProcedure()
    {
        Console.WriteLine("Hello World");
    }
}

为了拦截此类的方法以便记录它们,我正在创建另一个类(我的代理类版本),它实现相同的接口(interface)但包含对“真实”类的引用。此类执行一个操作(例如日志记录),然后在真实类上调用相同的方法。

例如:

class ProxyClass : IMyInterface
{
    private IMyInterface RealClass { get; set; }

    void MyProcedure()
    {
        // Log the call
        Console.WriteLine("Logging..");

        // Call the 'real' method
        RealClass.MyProcedure();
    }
}

调用者然后改为调用代理类上的所有方法(我使用基本的自制 IoC 容器来注入(inject)代理类代替真实类)。我使用此方法是因为我希望能够在运行时将 RealClass 换成另一个实现相同接口(interface)的类。

有没有办法在运行时创建 ProxyClass 并填充其 RealClass 属性,以便它可以用作真实类的代理?有没有一种简单的方法可以做到这一点,或者我是否需要使用类似 Reflection.Emit 的东西来生成 MSIL?

最佳答案

看看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);
        }
    }
}

以下是您将如何使用它:

IMyInterface intf = LoggingProxy<IMyInterface>.Create(new MyClass());
intf.MyProcedure();

控制台的输出将是:

在调用之前:MyProcedure
Hello World
调用后:MyProcedure

关于c# - 动态创建代理类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15733900/

相关文章:

c# - 如何在 Roslyn 上获取扩展方法?

c# - 克隆任意对象的函数

c# - 要求反射 API 覆盖 System.String.Empty 的含义是什么?

c# - 在 MVC 中绑定(bind)对象数组

c# - 从异常处理程序获取 ExitCode

c# - 使用 ServiceStack 3.9.56 找不到命名空间 ServiceStack.ServiceClient.Web

.net - 依赖注入(inject)和IDisposable

c# - 为什么不同版本的 Visual Studio 会输出相同代码的不同结果?

c# - 我可以防止通过公共(public) API 公开 3rd 方库的 'details' 吗?

java - java中的不可变类