From: hammett <ha...@uo...> - 2004-11-12 18:56:52
|
Hi Deyan, > About the mixins - I looked at the new mixin testcases you've included and > I > am afraid I don't understand how they can solve my problem .. If I create > a > MaterializeMixin with Materialize(int id) method, then I mix that one with > the Country class, and in the interceptor call > ((IMaterializable)invocation.Proxy).Materialize(_id); Yep.. > then how does this Materialize method fill the properties of the Country > class (I am not good with aspect terminology, but I assume that "mixin" > means that the methods of the classes are merged together, right?)? I > can't > write in the MaterializeMixin something like: The mixins interfaces are exposed by the proxy class, but the invocations on these methods (provided that the interceptor calls Proceed) delegates the invocation the the mixin instance. In your case it will be something like: class CountryProxy : Country, IMaterialize { private IMaterialize materialize; public CountryProxy( object[] mixins ) { this.materialize = (IMaterialize) mixins[0]; } } (This is a simplification, but depicts the essential pieces) > because it doesn't compile.. You have to define a protocol to allow the mixin to receive the proxy interface if they want. I decided to not put it there as it will overlap Aspect#'s protocol. Btw, you can see how Aspect# solves the same problem: http://cvs.sourceforge.net/viewcvs.py/aspectsharp/AspectSharp2/src/AspectSharpTests/MixinTests/MixinTestCase.cs?rev=1.5&view=auto See the MixinProxyAware test case. How this was implemented... Well, Aspect# adds a layer between itself and the DynamicProxy, so it can initialize the mixins: http://cvs.sourceforge.net/viewcvs.py/aspectsharp/AspectSharp2/src/AspectSharp/Core/Proxy/DefaultProxyFactory.cs?rev=1.6&view=auto See the InitializeMixins methods. Its very simple, really.. But if you dont want to use mixin, you implementation of IInterceptor could have an IMaterialize instance and could populate the proxy as well. > Please correct me if I am wrong, but in fact the proxy (by definition) > shouldn't populate itself, it should just materialize a inner (Country) > object, and then delegate all method invocations to the inner object, > without using reflection of course ... A simple delegation costs nothing > that's why the DynamicProxyAvalonTest should deliver comparable results if > the counter of the inner loop is increased ... Well, it doesn't have to be this way. I think my suggestion will have a better performance and its better than having two objects.. Believe, you can run into serious trouble with delegation if one of the methods is not virtual, like: class Country { public virtual String Name ... public virtual String Code .. public void SomeBusinessMethod(). } As this last method is not intercepted, the invocation would took place in a different instance with unpredictable results (Wow! I always wanted to say that one piece of my code could generate unpredictable results :-) ) Thats why I've changed so the IInvocationHandler to IInterceptor and added the Proceed.. The rationale is: you can delegate your calls to some other object, but we hope that you know the implications. The usual use won't do something like that. We can work on this one more time, if you send me again the code. -- Cheers, hammett http://www.digitalcraftsmen.com.br/~hammett |