在C#中实现动态代理的最佳方法是什么?
我需要在C#中创建动态代理。 我希望这个类包装另一个类,并采用它的公共接口,转发对这些函数的调用:
class MyRootClass { public virtual void Foo() { Console.Out.WriteLine("Foo!"); } } interface ISecondaryInterface { void Bar(); } class Wrapper : ISecondaryInterface where T: MyRootClass { public Wrapper(T otherObj) { } public void Bar() { Console.Out.WriteLine("Bar!"); } }
这是我想要使用它的方式:
Wrapper wrappedObj = new Wrapper(new MyRootClass()); wrappedObj.Bar(); wrappedObj.Foo();
生产:
Bar! Foo!
有任何想法吗?
最简单的方法是什么?
最好的方法是什么?
非常感谢。
UPDATE
我尝试遵循Wernight的建议并使用C#4.0动态代理实现此function。 不幸的是,我仍然被卡住了。 代理的要点是模仿通常(通常是)预期的其他接口。 使用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代码注入正在执行的方法的主体中。 (后尖锐)
- 运行时动态注入 – 使用reflection等技术,我们动态调用方法。
- 类型构建器注入 – 与运行时注入相关,我们基于我们希望代理的类型创建一个类型,然后通过此类型编组请求。 (动态代理)
- 容器注入 – 请求通过一个容器,该容器在执行方法之前和之后调用代码。
查看完整的文章 。
我知道Castle Project的动态代理经常被使用(就像Moq一样,只是为了命名一个大型项目)。
回复更新的主题
你写的不会编译。 动态代理是运行时生成的代码,因此您必须创建一个您正以某种方式代理的类的具体实例。 也许你正在寻找AOP (面向方面的编程)。
class MySecretProxy : DynamicObject, T where T : new() { private T _instance = new T(); public override void TryInvokeMember(...) { ... } } MySecretProxy bar;
你看过Castle项目的DynamicProxy吗? 它可能会提供您最终要实现的目标。 见http://www.castleproject.org/dynamicproxy/index.html
它也是开源的,所以如果需要你甚至可以分叉它。
如果目标Type是接口或派生自MarshalByRefObject,则可以使用RealProxy执行此操作。
您可能希望查看包含动态代理机制的linfu 。
我知道nhibernate用于延迟加载的代理
城堡
李林甫
Spring ByteCode