Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么';在C#中实现动态代理的最佳方法是什么?_C#_.net_.net 3.5_Dynamic Programming_Dynamic Proxy - Fatal编程技术网

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

什么';在C#中实现动态代理的最佳方法是什么?,c#,.net,.net-3.5,dynamic-programming,dynamic-proxy,C#,.net,.net 3.5,Dynamic Programming,Dynamic Proxy,我需要在C#中创建一个动态代理。我希望这个类包装另一个类,并使用它的公共接口,转发对这些函数的调用: class MyRootClass { public virtual void Foo() { Console.Out.WriteLine("Foo!"); } } interface ISecondaryInterface { void Bar(); } class Wrapper<T> : ISecondaryInterfac

我需要在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!");
    }
}
有什么想法吗

最简单的方法是什么

最好的方法是什么

非常感谢

更新

我尝试遵循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
 }

你看过城堡项目的DynamicProxy了吗?它可能提供你最终想要达到的目标。看


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

您可能想看看哪个包含动态代理机制。

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

城堡

临福


Spring字节码可以帮助您实现这一点

早期的.NET framework可以使用:

  • 面貌#
  • 封装AOP
  • Spring.NET
  • Aspect.NET
  • 方面
  • 动态代理
  • 谱写*
  • Loom.NET
  • 后夏普
这些框架中的每一个都使用了一些 代码注入技术 在合同执行之前和之后 方法。这些一般分为4类 类别

  • MSIL注入–这里我们将MSIL代码注入 正在执行的方法。(夏普邮报)
  • 运行时动态注入–使用反射等技术 动态调用方法
  • 类型生成器注入–与运行时注入相关,我们基于 我们希望代理的类型,然后通过此类型封送请求。(动态代理)
  • 容器注入–请求通过容器 它在我们的方法执行之前和之后调用代码

我知道Castle项目的动态代理经常被使用(比如在Moq中,仅举一个大型项目的名字)


回复更新的主题

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

类MySecretProxy:DynamicObject,T其中T:new()
{
私有T_实例=新T();
公共重写void TryInvokeMember(…){…}
}
MySecretProxy栏;

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

我简要地查看了它,这让我在这里提出了一个问题:“执行此操作的最简单方法是什么?”。它看起来像一个相当大的图书馆,我只打算使用一个小功能。有没有更简单的方法?你为什么担心图书馆的规模?您只需使用所需的功能。实际上,该文件(Castle.Core.dll)只有290KB。如果库满足了您的需求,那么使用它几乎肯定比自己重新发明这个特定的轮子要容易。大体上,我指的不是程序集的大小,而是需要学习和内部化才能正确使用的类/接口的数量。这是一个培训问题,而不是空间问题。如果你只打算使用图书馆的“一个小功能”,那么为什么你必须同时学习所有其他“功能”?如果您当前对它们不感兴趣,您可以忽略它们。这就像反对使用.NET框架本身的库的“一个小功能”,例如mscorlib,仅仅因为它有很多其他“功能”。你怎么能编译这样的东西呢?包装器没有一个Foo方法……这个主题写得很好,而且是一个很好的现实例子。但我仍然无法解决我的问题(请参阅相关更新)。您的代码没有编译,它给出错误“无法从'T'派生,因为它是一个类型参数”
Bar!
Foo!
class MySecretProxy : DynamicObject, ISecondaryInterface
{
    public override void TryInvokeMember(...) { .. }

    // no declaration of Bar -- let it be handled by TryInvokeMember
 }
class MySecretProxy<T> : DynamicObject, T where T : new()
{
    private T _instance = new T();

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

MySecretProxy<Bar> bar;