From: Darrick W. <da...@in...> - 2004-11-07 04:18:16
|
Hi guys, I have spent some time playing with Aspect# over the last couple of = days, and have a few things to report to HQ. I think what you have so = far is great stuff, and I'm really looking forward to using this in a = project some time soon! First, I should note that I am using the CLR 2.0 beta1 / VS 2005. That = said, the Aspect# 1.x version seemed to work fine, and this version = almost works, but sometimes methods that have valid pointcuts do not get = overridden by =20 Castle.DynamicProxy.ProxyGenerator. CreateCustomClassProxy(baseClass, = interceptor, context);=20 inside AspectSharp.Core.CustomProxyGenerator. CreateClassProxy(Type, = object[], IInterceptor). For instance, in the example program that you = provide, the MixinAndInterceptorExecution function works correctly, but = the HashTableTest runs but get_Item is not intercepted, and using = reflection I can see that the DeclaringType of get_Item is still = HashTable. I spent a lot of time on this but I could not find an error = in your code, and I couldn't find the source for Castle.DynamicProxy = (the one I found at Apache.Avalon was quite different). Secondly, I found that the cache in AspectSharp.Core.Proxy. = DefaultProxyFactory did not work if the aspect was operating on more = than one type. I think the problem only surfaced the second time that = the second class was wrapped. Making the following change and adding an = apropriate AspectInstanceKey class as below fixed this: private Type GetProxyTypeFromCache (AspectDefinition aspect, Type = baseClass) { return _aspect2ProxyType[new AspectInstanceKey(aspect, baseClass)] = as Type; } private void RegisterProxyTypeInCache (AspectDefinition aspect, Type = baseClass, Type proxyType) { _aspect2ProxyType[new AspectInstanceKey(aspect, baseClass)] =3D = proxyType; } Third, I discovered that the parser does not treat '_' as an ID token. = I have fixed this as well. Fourth, I have extended the method interceptor pointcut definition so = that we can specify the accessibility of the method we want to = intercept. The original syntax still works, but now we can also have: pointcut method(public * *) pointcut method(* void *(*)) pointcut method(internal * Method.*()) etc. Finally, just for fun I added this function to the AspectEngine. I = think it has potential although it is nothing particularly spectacular = right now, so I thought I'd pass it along. public virtual TypeToWrap WrapClass<TypeToWrap>() { return (TypeToWrap)WrapClass(typeof(TypeToWrap)); } called: ISomeClass d =3D engine.WrapClass<SomeClass>(); Cheers! Darrick Wiebe |
From: hammett <ha...@uo...> - 2004-11-07 16:44:34
|
Hy Darrick, Thanks for the feedback. The Castle.DynamicProxy source can be checked out from SVN repository at https://207.234.145.146/svn/castle/trunk/Tools/DynamicProxy/ > I have spent some time playing with Aspect# over the last couple of days, > and > have a few things to report to HQ. I think what you have so far is great > stuff, > and I'm really looking forward to using this in a project some time soon! Nice! :-) > First, I should note that I am using the CLR 2.0 beta1 / VS 2005. That > said, > the Aspect# 1.x version seemed to work fine, and this version almost > works, > but sometimes methods that have valid pointcuts do not get overridden by Well, I think thats the first time it has been tested against CLR 2.0. I don't even want to install the CLR 2.0 as it will make the NCover stop working.. :-( > inside AspectSharp.Core.CustomProxyGenerator. CreateClassProxy(Type, > object[], IInterceptor). For instance, in the example program that you > provide, > the MixinAndInterceptorExecution function works correctly, but the > HashTableTest > runs but get_Item is not intercepted, and using reflection I can see that > the > DeclaringType of get_Item is still HashTable. I spent a lot of time on > this but > I could not find an error in your code, and I couldn't find the source for > Castle. > DynamicProxy (the one I found at Apache.Avalon was quite different). Yeah, you're right. This's broken since my major refactoring, I havent noticed... The get_Item is being intercepted correctly by the proxy, but no matching is found (for some reason). I'll dig for the reason later today. > Secondly, I found that the cache in AspectSharp.Core.Proxy. > DefaultProxyFactory > did not work if the aspect was operating on more than one type. I think > the problem > only surfaced the second time that the second class was wrapped. Making > the > following change and adding an apropriate AspectInstanceKey class as below > fixed this: Applied! Thanks > Fourth, I have extended the method interceptor pointcut definition so that > we can specify > the accessibility of the method we want to intercept. The original syntax > still works, but > now we can also have: > > pointcut method(public * *) > pointcut method(* void *(*)) > pointcut method(internal * Method.*()) Nice! > Finally, just for fun I added this function to the AspectEngine. I think > it has potential > although it is nothing particularly spectacular right now, so I thought > I'd pass it along. > public virtual TypeToWrap WrapClass<TypeToWrap>() > { > return (TypeToWrap)WrapClass(typeof(TypeToWrap)); > } > called: > ISomeClass d = engine.WrapClass<SomeClass>(); This is nice, but depends on the CLR 2.0. In a near future we can provide two distributions. I'm looking forward for your patch! -- Cheers, hammett http://www.digitalcraftsmen.com.br/~hammett |
From: hammett <ha...@uo...> - 2004-11-07 21:32:52
|
> Yeah, you're right. This's broken since my major refactoring, I havent > noticed... The get_Item is being intercepted correctly by the proxy, but > no matching is found (for some reason). > I'll dig for the reason later today. Fixed. That was a DynamicProxy properties generation problem. I was ignoring the arguments. So ashamed! :-( I'll wait for the Darrick patch and release the beta 2 as soon as possible. Cheers! |
From: Mike D. <mik...@gm...> - 2004-11-11 20:05:02
|
Hi Hammett! I'm working on getting the code for NHibernate to use the latest DynamicProxy code and am running into some problems :) One of the problems I'm having is around serialization of the proxies. In your old version the method GetObjectData() was passed to the IInvocationHandler. In the new version it looks like GetObjectData is completely handled by the DynamicProxy and never handled by IInvocation - is that true or am I doing something wrong? My old logic was to serialize the class instance that was being proxied if it has been read from the db, or if the class had not been instantiated yet then serialize a class that was capable of recreating the proxy during deserialization. I'm open for any suggestions on how to handle this with the new code base. Thanks! Mike |
From: hammett <ha...@uo...> - 2004-11-11 20:35:07
|
Hey Mike, > In the new version it looks like GetObjectData is > completely handled by the DynamicProxy and never handled by > IInvocation - is that true or am I doing something wrong? Yes, you're right. > My old logic was to serialize the class instance that was being > proxied if it has been read from the db, or if the class had not been > instantiated yet then serialize a class that was capable of recreating > the proxy during deserialization. I'm open for any suggestions on how > to handle this with the new code base. Well, this is what the GetObjectData implementation in the proxy does... But, to be sure that we are on the same page, can you please direct me to the source code of the old logic? -- Cheers, hammett http://www.digitalcraftsmen.com.br/~hammett |
From: Mike D. <mik...@gm...> - 2004-11-11 20:39:24
|
This is the base class where most of the proxy work is handled. The method Invoke at the bottom contains the logic. http://cvs.sourceforge.net/viewcvs.py/nhibernate/nhibernate/src/NHibernate/Proxy/LazyInitializer.cs?rev=1.1.2.5&only_with_tag=alpha_avalon-proxy&view=auto Here's the class the proxy used to get serialized as and deserialized from. http://cvs.sourceforge.net/viewcvs.py/nhibernate/nhibernate/src/NHibernate/Proxy/Attic/AvalonProxyDeserializer.cs?rev=1.1.2.2&only_with_tag=alpha_avalon-proxy&view=auto Thanks for such as fast response! Mike On Thu, 11 Nov 2004 18:34:41 -0800, hammett <ha...@uo...> wrote: > Hey Mike, > > > In the new version it looks like GetObjectData is > > completely handled by the DynamicProxy and never handled by > > IInvocation - is that true or am I doing something wrong? > > Yes, you're right. > > > My old logic was to serialize the class instance that was being > > proxied if it has been read from the db, or if the class had not been > > instantiated yet then serialize a class that was capable of recreating > > the proxy during deserialization. I'm open for any suggestions on how > > to handle this with the new code base. > > Well, this is what the GetObjectData implementation in the proxy does... > But, to be sure that we are on the same page, can you please direct me to > the source code of the old logic? > > -- > Cheers, > hammett > http://www.digitalcraftsmen.com.br/~hammett > > |
From: hammett <ha...@uo...> - 2004-11-11 21:08:29
|
Then yes, we are on the same page :-) Your AvalonProxyDeserializer is a simplified version of ours: http://svn.digitalcraftsmen.com.br/svn/castle/trunk/Tools/DynamicProxy/DynamicProxy/Serialization/ProxyObjectReference.cs The only difference I've notice (although I havent checked it carefully) is that you provide a hook allowing subclasses to add entries to SerializationInfo. This is not possible in DynProxy as it is. However, if the class being proxy exposes a virtual GetObjectData, it will be (correctly) invoked. My suggestion is: move all information necessary to the implementation of IInterceptor (that's what we have done to Aspect#, so when a class with aspect is deserialized, the interceptor has all information about the pointcuts and advices it needs) http://cvs.sourceforge.net/viewcvs.py/aspectsharp/AspectSharp2/src/AspectSharp/Core/Dispatcher/DefaultInvocationDispatcher.cs?rev=1.4&view=auto -- Cheers, hammett http://www.digitalcraftsmen.com.br/~hammett ----- Original Message ----- From: "Mike Doerfler" <mik...@gm...> To: <asp...@li...> Sent: Thursday, November 11, 2004 12:39 PM Subject: Re: [Aspectsharp-users] Implementation of GetObjectData > This is the base class where most of the proxy work is handled. The > method Invoke at the bottom contains the logic. > > http://cvs.sourceforge.net/viewcvs.py/nhibernate/nhibernate/src/NHibernate/Proxy/LazyInitializer.cs?rev=1.1.2.5&only_with_tag=alpha_avalon-proxy&view=auto > > > Here's the class the proxy used to get serialized as and deserialized > from. > > http://cvs.sourceforge.net/viewcvs.py/nhibernate/nhibernate/src/NHibernate/Proxy/Attic/AvalonProxyDeserializer.cs?rev=1.1.2.2&only_with_tag=alpha_avalon-proxy&view=auto > > Thanks for such as fast response! |
From: Mike D. <mik...@gm...> - 2004-11-11 22:24:23
|
Thanks for the quick replies Hammett! Mike On Thu, 11 Nov 2004 19:08:09 -0800, hammett <ha...@uo...> wrote: > Then yes, we are on the same page :-) > > Your AvalonProxyDeserializer is a simplified version of ours: > http://svn.digitalcraftsmen.com.br/svn/castle/trunk/Tools/DynamicProxy/DynamicProxy/Serialization/ProxyObjectReference.cs > > The only difference I've notice (although I havent checked it carefully) is > that you provide a hook allowing subclasses to add entries to > SerializationInfo. This is not possible in DynProxy as it is. However, if > the class being proxy exposes a virtual GetObjectData, it will be > (correctly) invoked. My suggestion is: move all information necessary to the > implementation of IInterceptor (that's what we have done to Aspect#, so when > a class with aspect is deserialized, the interceptor has all information > about the pointcuts and advices it needs) > > http://cvs.sourceforge.net/viewcvs.py/aspectsharp/AspectSharp2/src/AspectSharp/Core/Dispatcher/DefaultInvocationDispatcher.cs?rev=1.4&view=auto > > -- > > > Cheers, > hammett > http://www.digitalcraftsmen.com.br/~hammett > > ----- Original Message ----- > From: "Mike Doerfler" <mik...@gm...> > To: <asp...@li...> > Sent: Thursday, November 11, 2004 12:39 PM > Subject: Re: [Aspectsharp-users] Implementation of GetObjectData > > > This is the base class where most of the proxy work is handled. The > > method Invoke at the bottom contains the logic. > > > > http://cvs.sourceforge.net/viewcvs.py/nhibernate/nhibernate/src/NHibernate/Proxy/LazyInitializer.cs?rev=1.1.2.5&only_with_tag=alpha_avalon-proxy&view=auto > > > > > > Here's the class the proxy used to get serialized as and deserialized > > from. > > > > http://cvs.sourceforge.net/viewcvs.py/nhibernate/nhibernate/src/NHibernate/Proxy/Attic/AvalonProxyDeserializer.cs?rev=1.1.2.2&only_with_tag=alpha_avalon-proxy&view=auto > > > > Thanks for such as fast response! > > |