繁体   English   中英

在C#中实现动态代理的最佳方法是什么?

[英]What's the best way to implement a dynamic proxy in C#?

我需要在C#中创建动态代理。 我希望这个类包装另一个类,并采用它的公共接口,转发对这些函数的调用:

class MyRootClass
{
    public virtual void Foo()
    {
        Console.Out.WriteLine("Foo!");
    }

}

interface ISecondaryInterface
{
    void Bar();
}

class Wrapper<T> : ISecondaryInterface where T: MyRootClass
{
    public Wrapper(T otherObj)
    {
    }

    public void Bar()
    {
        Console.Out.WriteLine("Bar!");
    }
}

这是我想要使用它的方式:

Wrapper<MyRootClass> wrappedObj = new Wrapper<MyRootClass>(new MyRootClass());
wrappedObj.Bar();
wrappedObj.Foo();

生产:

Bar!
Foo!

有任何想法吗?

最简单的方法是什么?

最好的方法是什么?

非常感谢。

UPDATE

我尝试遵循Wernight的建议并使用C#4.0动态代理实现此功能。 不幸的是,我仍然被卡住了。 代理的要点是模仿通常(通常是)预期的其他接口。 使用DynamicObject要求我将其所有客户端更改为使用“dynamic”而不是“ISecondaryInterface”。

有没有办法获取代理对象,这样当它包装A时,它会(静态地)通告它支持A的接口; 当它包装B时,它会宣传支持B的界面?

更新2

例如:

class MySecretProxy : DynamicObject, ISecondaryInterface
{
    public override void TryInvokeMember(...) { .. }

    // no declaration of Bar -- let it be handled by TryInvokeMember
 }

.NET 4 DynamicObject可以帮助您实现这一目标。

早期的.NET框架可以使用:

  • 方面#
  • Encase AOP
  • Spring.NET
  • Aspect.NET
  • AspectDNG
  • 动态代理
  • 撰写*
  • Loom.NET
  • PostSharp

这些框架中的每一个都使用多种技术来在执行方法之前和之后注入代码。 这些通常分为4类。

  • MSIL注入 - 这里我们将MSIL代码注入正在执行的方法的主体中。 (后尖锐)
  • 运行时动态注入 - 使用反射等技术,我们动态调用方法。
  • 类型构建器注入 - 与运行时注入相关,我们根据我们希望代理的类型创建一个类型,然后通过此类型编组请求。 (动态代理)
  • 容器注入 - 请求通过一个容器,该容器在执行方法之前和之后调用代码。

查看完整的文章

我知道Castle Project动态代理经常被使用(就像在Moq中命名一个大型项目一样)。


回复更新的主题

你写的不会编译。 动态代理是运行时生成的代码,因此您必须创建以某种方式代理的类的具体实例。 也许你正在寻找AOP (面向方面​​编程)。

class MySecretProxy<T> : DynamicObject, T where T : new()
{
    private T _instance = new T();

    public override void TryInvokeMember(...) { ... }
}

MySecretProxy<Bar> bar;

你看过Castle项目的DynamicProxy吗? 它可能会提供您最终要实现的目标。 http://www.castleproject.org/dynamicproxy/index.html

它也是开源的,所以你甚至可以根据需要进行分叉。

如果目标Type是接口或派生自MarshalByRefObject,则可以使用RealProxy执行此操作。

您可能希望查看包含动态代理机制的linfu

我知道nhibernate用于延迟加载的代理

城堡

李林甫

Spring ByteCode

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM