| Joe Walnes |
|
|||||||||||||||||
|
|
|
|
||||||||||||||||
|
How to do Dynamic Proxies in C#Background: A dynamic proxy dynamically generates a class at runtime that conforms to a particular interface, proxying all invocations to a single 'generic' method. Earlier, Stellsmi asked if it's possible to do this in .NET (it's a standard part of Java). Seeing as it's the second time I've talked about it in as many days, I reckon it's worth blogging... As far as I know, there are two ways to do this:
The first approach is pretty trivial, but it locks you into the fact that you can only proxy objects that extend ContextBound. Not ideal as this pulls a lot of stuff into your class you don't necessarily need and prevents you from inheriting something else. The second approach is more suitable, less intrusive, but not pretty to write as it involves writing low-level IL op-codes. However, I did this already in NMock and at GeekNight, Steve and Jon lovingly decoupled the ClassGenerator from the core of NMock, so you can create generic dynamic proxies. So now it's easy to create a proxy. ExampleHere's an interface you want to create a dynamic proxy for:
Note:
To create the proxy, you need to create an implementation of IInvocationHandler. This is called any time a method is invoked on the proxy.
Notes:
Finally, you need to generate the proxy itself so you can actually use the damn thing: ClassGenerator generator = new ClassGenerator( typeof(Foo), new MyHandler() ); IFoo fooProxy = (IFoo)generator.Generate(); string result = fooProxy.DoStuff(2); // returns "hello from DoStuff" Ermm and that's it! Use your dynamic proxy like it's a real class. ClassGenerator is part of the NMock library. Use it for AOP style interceptors, decorators, stubbing, mocking :), whatever. Brain rumblings... Hmm... maybe that should be a delegate instead... maybe I should revisit some stuff... CommentsI thought there was some kind of Code DOM in .NET that lets you define and compile code without having to fiddle with byte codes. Joe WalnesYes there is, but there's a high overhead in invoking the compiler each time you want to create a new proxy, so I didn't consider it. Stefan ZobelGreat work! I started to implement this myself last year since it is such a useful functionality to have (I always wondered why Microsoft missed this in the .NET Framework). Could you please supply a source distributon of NMock on sourceforge? Personally, I prefer to browse the code locally and I hate working with CVS remotely. Regards, Stefan homer jayI gotta look into C# a little further. It looks pretty cool! Jason BockAnother Reflection.Emit approach is what I did in Chapter 8 of my CIL book. You can get the code here: http://www.apress.com/book/supplementDownload.html?bID=88&sID=525 Regards, Jason Jeppe CramonThis is really neat:) /Jeppe SebHi, I wrote an article (in french) about Reflection.Emit proxies (simulates the Java way of doing it), along with full source code that should be in english Check it out at : -S GillesYour solution don't work for an 'Arraylist' proxy, see below, there's a bug on the Add(5) ClassGenerator generatorList = new ClassGenerator( Chris BrownJoe, This is exactly what I've been looking for I've tried a few differnent approaches to implement AOP intercepters, Code DOM (but I don't want to write a parser or recompile the code), Real Proxys (but I don't want all objects to be ContextBound) or Reflection.Emit (I don't want to learn IL) Sounds like you done the leg work for me. Thanks JackJoe - FANTASTIC WORK. Gilles mentions a bug above. Is this fixed? Seb - have you considered translating your article to english? Toney AlguireNice work, but there is a flaw that should be removed. In java, a reference to the object on which the proxy is called is passed to the invoke method as the first parameter. This is extremely useful and actually required by several application I've been working on in java. One example is when the creation process associates data with the instance (such as an database OID). But there is no way of getting the instance from the proxy. Could you elaborate about how to extend the ClassGenerator class to support this functionality? exortechbtw, you don't need to extend ContextBoundObject to do interception using RealProxy. you can extend MarshalByRef instead. it is much more performant than CBO, and plus, you are more likely to have a use for MBOs when using remoting. makes building interceptors for remote objects quite easy. SebHi, the article mentioned in my previous post gave birth to a gotdotnet workspace at http://workspaces.gotdotnet.com/dynaprox Fell free to join ! -S PoliWhat about Castle Dynamic Proxy ??? http://www.castleproject.org/index.php/DynamicProxy standard chair lose or notNice post. I'll return. faithful, central, astonishing nothing comparative to tremendous international round do or notYour site is exactly the kind of sites which make the net surfing so fun. to fetch opponents you should be very universal BritneyHello, nice site look this: End ^) See you HillaryHello, nice site look this: End ^) See you BritneyHello, nice site look this: End ^) See you Dwayne JohnsonI love this site, there is so much information to be found. Thank you. no consultationintercepting plasterer detains cremations!singsong testifying protruded:torturing Poorret[URL=http://blow-job-clip.ubmission.cn]blow job clip[/URL] Poorret[URL=http://teacher-fucking.tsukishima.cn]teacher fucking[/URL] |
|
||||||||||||||||
|
[RSS | RDF] © 2001-2004, Joe Walnes |
Powered by SiteMesh and Moveable Type. | |||||||||||||||||