From: Michael D. <mik...@us...> - 2004-10-03 18:20:48
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Proxy In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7021/Proxy Modified Files: Tag: alpha_avalon-proxy AvalonLazyInitializer.cs AvalonProxyGenerator.cs IProxyGenerator.cs LazyInitializer.cs ProxyGeneratorFactory.cs Added Files: Tag: alpha_avalon-proxy AvalonProxyDeserializer.cs Removed Files: Tag: alpha_avalon-proxy SerializableProxy.cs Log Message: serialization of proxies is now working. Index: AvalonProxyGenerator.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Proxy/Attic/AvalonProxyGenerator.cs,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** AvalonProxyGenerator.cs 27 Sep 2004 03:42:03 -0000 1.1.2.1 --- AvalonProxyGenerator.cs 3 Oct 2004 16:58:13 -0000 1.1.2.2 *************** *** 2,7 **** --- 2,10 ---- using System.Collections; using System.Reflection; + using System.Reflection.Emit; using Apache.Avalon.DynamicProxy; + using Apache.Avalon.DynamicProxy.Builder; + using Apache.Avalon.DynamicProxy.Builder.CodeGenerators; using NHibernate.Engine; *************** *** 10,14 **** { /// <summary> ! /// An <see cref="IProxyGenerator"/> for the Apache.Avalon.DynamicProxy library. /// </summary> public class AvalonProxyGenerator : IProxyGenerator --- 13,17 ---- { /// <summary> ! /// An <see cref="IProxyGenerator"/> that uses the Apache.Avalon.DynamicProxy library. /// </summary> public class AvalonProxyGenerator : IProxyGenerator *************** *** 16,20 **** private static readonly log4net.ILog log = log4net.LogManager.GetLogger( typeof(AvalonProxyGenerator) ); ! private ProxyGenerator _generator = new ProxyGenerator(); /// <summary> --- 19,25 ---- private static readonly log4net.ILog log = log4net.LogManager.GetLogger( typeof(AvalonProxyGenerator) ); ! private ProxyGenerator _generator; ! private DefaultProxyBuilder _defaultBuilder; ! private GeneratorContext _context; /// <summary> *************** *** 22,26 **** /// </summary> internal AvalonProxyGenerator() ! { } --- 27,59 ---- /// </summary> internal AvalonProxyGenerator() ! { ! _defaultBuilder = new DefaultProxyBuilder( ); ! ! // the EnhanceTypeDelegate will add custom code gen that DynamicProxy does not provide ! // by default. ! _context = new GeneratorContext( new EnhanceTypeDelegate( EnhanceInterfaceType ), null ); ! ! // only create the genator once so I should be okay with the DefaultProxyBuilder ! // maintaining the ModuleScope ! _generator = new ProxyGenerator(); ! ! } ! ! /// <summary> ! /// Marks the Proxy with the <see cref="SerializableAttribute"/>. ! /// </summary> ! /// <param name="mainType"></param> ! /// <param name="handlerFieldBuilder"></param> ! /// <param name="constructorBuilder"></param> ! /// <remarks> ! /// The proxy itself is not really serializable, it is replaced with a different object during ! /// serialization. This object knows how to recreate the proxy during the deserialization ! /// process. ! /// </remarks> ! private void EnhanceInterfaceType(TypeBuilder mainType, FieldBuilder handlerFieldBuilder, ConstructorBuilder constructorBuilder) ! { ! ConstructorInfo serAttConstructor = typeof(SerializableAttribute).GetConstructor( new System.Type[0] ); ! CustomAttributeBuilder serializableAttBuilder = new CustomAttributeBuilder( serAttConstructor, new object[0] ); ! mainType.SetCustomAttribute( serializableAttBuilder ); } *************** *** 54,58 **** } ! object generatedProxy = _generator.CreateProxy( interfaces, initializer ); return (INHibernateProxy)generatedProxy; --- 87,92 ---- } ! System.Type proxyType = _defaultBuilder.CreateCustomInterfaceProxy( interfaces, _context ); ! object generatedProxy = Activator.CreateInstance( proxyType, new object[] { initializer } ); return (INHibernateProxy)generatedProxy; *************** *** 66,70 **** #endregion - } } --- 100,103 ---- Index: IProxyGenerator.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Proxy/Attic/IProxyGenerator.cs,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** IProxyGenerator.cs 27 Sep 2004 03:42:03 -0000 1.1.2.1 --- IProxyGenerator.cs 3 Oct 2004 16:58:13 -0000 1.1.2.2 *************** *** 22,27 **** /// <returns>A fully built <c>INHibernateProxy</c>.</returns> INHibernateProxy GetProxy(System.Type persistentClass, System.Type[] interfaces, PropertyInfo identifierPropertyInfo, object id, ISessionImplementor session); - - } } --- 22,25 ---- Index: LazyInitializer.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Proxy/LazyInitializer.cs,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** LazyInitializer.cs 27 Sep 2004 03:42:03 -0000 1.1.2.1 --- LazyInitializer.cs 3 Oct 2004 16:58:13 -0000 1.1.2.2 *************** *** 2,5 **** --- 2,6 ---- using System.Collections; using System.Reflection; + using System.Runtime.Serialization; using NHibernate.Engine; *************** *** 31,36 **** protected PropertyInfo _identifierPropertyInfo; protected bool _overridesEquals; ! private SerializableProxy _serializableProxy; ! /// <summary> /// Create a LazyInitializer to handle all of the Methods/Properties that are called --- 32,36 ---- protected PropertyInfo _identifierPropertyInfo; protected bool _overridesEquals; ! /// <summary> /// Create a LazyInitializer to handle all of the Methods/Properties that are called *************** *** 99,107 **** /// <summary> ! /// Converts this Proxy into a Serializable Class that knows how to create a ! /// Proxy during the Deserialization process. /// </summary> ! /// <returns>SerializableProxy that can Deserialize this LazyInitializer.</returns> ! protected abstract SerializableProxy SerializableProxy() ; public object Identifier --- 99,108 ---- /// <summary> ! /// Adds all of the information into the SerializationInfo that is needed to ! /// reconstruct the proxy during deserialization or to replace the proxy ! /// with the instantiated target. /// </summary> ! /// <param name="info">The <see cref="SerializationInfo"/> to write the object to.</param> ! protected abstract void AddSerailizationInfo(SerializationInfo info); public object Identifier *************** *** 172,180 **** /// which indicates that the Proxy will need to forward to the real implementation. /// </returns> ! public virtual object Invoke(MethodInfo method, params object[] args) { // all Proxies must implement INHibernateProxy which extends ISerializable if( method.Name.Equals("GetObjectData") ) { if( _target==null & _session!=null ) { --- 173,184 ---- /// which indicates that the Proxy will need to forward to the real implementation. /// </returns> ! public virtual object Invoke(MethodBase method, params object[] args) { // all Proxies must implement INHibernateProxy which extends ISerializable if( method.Name.Equals("GetObjectData") ) { + SerializationInfo info = (SerializationInfo)args[0]; + StreamingContext context = (StreamingContext)args[1]; + if( _target==null & _session!=null ) { *************** *** 183,198 **** } ! if( _target==null ) ! { ! if( _serializableProxy==null ) ! { ! _serializableProxy = SerializableProxy(); ! } ! return _serializableProxy; ! } ! else ! { ! return _target; ! } } else if( !_overridesEquals && _identifierPropertyInfo!=null && method.Name.Equals("GetHashCode") ) --- 187,196 ---- } ! // let the specific LazyInitializer write its requirements for deserialization ! // into the stream. ! AddSerailizationInfo( info ); ! ! // don't need a return value for proxy. ! return null; } else if( !_overridesEquals && _identifierPropertyInfo!=null && method.Name.Equals("GetHashCode") ) *************** *** 204,208 **** } else if( _identifierPropertyInfo!=null && method.Equals( _identifierPropertyInfo.GetGetMethod(true) ) ) - // .Name.Equals( "get_" + _identifierPropertyInfo.Name ) ) -> this was removed because of null _identifierPropertyInfo problems { return _id; --- 202,205 ---- *************** *** 225,297 **** } - - #region Helper Class for all of the Parameters to InvokeMember - - protected class InvokeMemberParams - { - private string _methodName; - private BindingFlags _invokeAttr; - private static IDictionary _knownPrefixes; - - static InvokeMemberParams () - { - BindingFlags defaultFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; - _knownPrefixes = new Hashtable(6); - _knownPrefixes.Add("", defaultFlags | BindingFlags.InvokeMethod); - _knownPrefixes.Add("get", defaultFlags | BindingFlags.GetProperty); - _knownPrefixes.Add("set", defaultFlags | BindingFlags.SetProperty); - } - - private InvokeMemberParams(string methodName, BindingFlags invokeAttr) - { - _methodName = methodName; - _invokeAttr = invokeAttr; - } - - public BindingFlags InvokeAttr - { - get { return _invokeAttr; } - } - - public string MethodName - { - get { return _methodName; } - } - - public static InvokeMemberParams GetInvokeMemberParams(string methodName) - { - int indexOfFirstUnderscore = methodName.IndexOf("_"); - string prefix = String.Empty; - - string method; - BindingFlags flags; - - // there was no underscore found in the name - has to be a method that - // is being called. - if(indexOfFirstUnderscore==-1) - { - return new InvokeMemberParams(methodName, (BindingFlags)_knownPrefixes[""] ); - } - - prefix = methodName.Substring(0, indexOfFirstUnderscore); - - // there was an underscore found - is this a property get_/set_ or just a bad naming - // convention that someone is following - if(_knownPrefixes.Contains(prefix)) - { - method = methodName.Substring(indexOfFirstUnderscore + 1, methodName.Length - (indexOfFirstUnderscore + 1) ); - flags = (BindingFlags)_knownPrefixes[prefix]; - - return new InvokeMemberParams(method, flags); - } - else - { - // bad naming convention was used - an "_" in a method name??? - return new InvokeMemberParams(methodName, (BindingFlags)_knownPrefixes[""] ); - } - } - } - #endregion - } } --- 222,225 ---- --- SerializableProxy.cs DELETED --- Index: AvalonLazyInitializer.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Proxy/Attic/AvalonLazyInitializer.cs,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** AvalonLazyInitializer.cs 27 Sep 2004 03:42:03 -0000 1.1.2.1 --- AvalonLazyInitializer.cs 3 Oct 2004 16:58:13 -0000 1.1.2.2 *************** *** 2,5 **** --- 2,6 ---- using System.Collections; using System.Reflection; + using System.Runtime.Serialization; using Apache.Avalon.DynamicProxy; *************** *** 10,14 **** { /// <summary> ! /// A <see cref="NLazyInitiliazer"/> built using Avalon's Dynamic Class Generator. /// </summary> public class AvalonLazyInitializer : LazyInitializer, IInvocationHandler --- 11,15 ---- { /// <summary> ! /// A <see cref="LazyInitiliazer"/> for use with Avalon's Dynamic Class Generator. /// </summary> public class AvalonLazyInitializer : LazyInitializer, IInvocationHandler *************** *** 33,39 **** ! protected override SerializableProxy SerializableProxy() { ! return new SerializableProxy( _persistentClass, _interfaces, _id, _identifierPropertyInfo ); } --- 34,48 ---- ! protected override void AddSerailizationInfo(SerializationInfo info) { ! // the AvalonProxyDeserializer will be the Type that is actually serialized for this ! // proxy. ! info.SetType( typeof(AvalonProxyDeserializer) ); ! ! info.AddValue( "_target", _target ); ! info.AddValue( "_persistentClass", _persistentClass ); ! info.AddValue( "_interfaces", _interfaces ); ! info.AddValue( "_identifierPropertyInfo", _identifierPropertyInfo ); ! info.AddValue( "_id", _id ); } *************** *** 51,59 **** object result = base.Invoke( method, arguments ); ! // the base NLazyInitializer could not handle it so we need to Invoke // the method/property against the real class. if(result==InvokeImplementation) { - InvokeMemberParams invokeParams = InvokeMemberParams.GetInvokeMemberParams( method.Name ); return method.Invoke( GetImplementation(), arguments ); } --- 60,67 ---- object result = base.Invoke( method, arguments ); ! // the base LazyInitializer could not handle it so we need to Invoke // the method/property against the real class. if(result==InvokeImplementation) { return method.Invoke( GetImplementation(), arguments ); } Index: ProxyGeneratorFactory.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Proxy/Attic/ProxyGeneratorFactory.cs,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** ProxyGeneratorFactory.cs 27 Sep 2004 03:42:03 -0000 1.1.2.1 --- ProxyGeneratorFactory.cs 3 Oct 2004 16:58:13 -0000 1.1.2.2 *************** *** 15,19 **** private static readonly log4net.ILog log = log4net.LogManager.GetLogger( typeof(ProxyGeneratorFactory) ); ! private static AvalonProxyGenerator _generator = new AvalonProxyGenerator(); public static IProxyGenerator GetProxyGenerator() --- 15,19 ---- private static readonly log4net.ILog log = log4net.LogManager.GetLogger( typeof(ProxyGeneratorFactory) ); ! private static IProxyGenerator _generator = new AvalonProxyGenerator(); public static IProxyGenerator GetProxyGenerator() --- NEW FILE: AvalonProxyDeserializer.cs --- using System; using System.Reflection; using System.Runtime.Serialization; namespace NHibernate.Proxy { /// <summary> /// Deserializes an Avalon generated Proxy into either another Proxy that is regenerated /// or into the target that the generated Proxy was proxying. /// </summary> [Serializable] public class AvalonProxyDeserializer : IObjectReference { // these fields are set during the GetObjectData call in AvalonLazyInitializer. private object _target = null; private System.Type _persistentClass = null; private System.Type[] _interfaces = null; private PropertyInfo _identifierPropertyInfo = null; private object _id = null; #region IObjectReference Members /// <summary> /// Converts a SerializableProxy into the dynamically generated Proxy on the Client side /// or just returns the object that was the target behind the Proxy if it was loaded. /// </summary> /// <param name="context"></param> /// <returns></returns> public object GetRealObject(StreamingContext context) { if( _target==null ) { IProxyGenerator generator = ProxyGeneratorFactory.GetProxyGenerator(); object proxy = generator.GetProxy( _persistentClass , _interfaces , _identifierPropertyInfo , _id , null ); return proxy; } else { // this object was not serialized as a proxy but instead as the real object // there is nothing to do with it other than return it and let the framework // put it into the deserialized object stream. return _target; } } #endregion } } |