5

我需要在 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!

有任何想法吗?

最简单的方法是什么?

最好的方法是什么?

非常感谢。

更新

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

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

更新 2

例如:

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

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

5 回答 5

7

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

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

  • 方面#
  • 封装 AOP
  • 春天.NET
  • 方面.NET
  • AspectDNG
  • 动态代理
  • 撰写*
  • 织机网
  • 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;
于 2011-06-06T08:43:52.563 回答
3

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

它也是开源的,因此您甚至可以在需要时分叉它。

于 2011-01-04T19:50:21.400 回答
1

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

于 2011-07-14T16:29:42.200 回答
0

您可能想查看包含动态代理机制的linfu 。

于 2011-01-04T19:53:52.087 回答
0

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

城堡

临府

春天字节码

于 2011-01-04T19:55:26.143 回答