private void CreateProxiedMethod(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField)
 {
     if (method == NHibernateProxyTypeLazyInitializerProperty.GetMethod)
     {
         ImplementGetLazyInitializer(typeBuilder, method, lazyInitializerField);
     }
     else if (method == _getIdentifierMethod)
     {
         ImplementGetIdentifier(typeBuilder, method, lazyInitializerField);
     }
     else if (method == _setIdentifierMethod)
     {
         ImplementSetIdentifier(typeBuilder, method, lazyInitializerField);
     }
     else if (!_overridesEquals && method.Name == "Equals" && method.GetBaseDefinition() == typeof(object).GetMethod("Equals", new[] { typeof(object) }))
     {
         //skip
     }
     else if (!_overridesEquals && method.Name == "GetHashCode" && method.GetBaseDefinition() == typeof(object).GetMethod("GetHashCode"))
     {
         //skip
     }
     else if (_componentIdType != null && _componentIdType.IsMethodOf(method))
     {
         ImplementCallMethodOnEmbeddedComponentId(typeBuilder, method, lazyInitializerField);
     }
     else
     {
         ImplementCallMethodOnImplementation(typeBuilder, method, lazyInitializerField);
     }
 }
Beispiel #2
0
        /// <summary>
        /// Invokes the method if this is something that the LazyInitializer can handle
        /// without the underlying proxied object being instantiated.
        /// </summary>
        /// <param name="method">The name of the method/property to Invoke.</param>
        /// <param name="args">The arguments to pass the method/property.</param>
        /// <param name="proxy">The proxy object that the method is being invoked on.</param>
        /// <returns>
        /// The result of the Invoke if the underlying proxied object is not needed.  If the
        /// underlying proxied object is needed then it returns the result <see cref="AbstractLazyInitializer.InvokeImplementation"/>
        /// which indicates that the Proxy will need to forward to the real implementation.
        /// </returns>
        public virtual object Invoke(MethodInfo method, object[] args, object proxy)
        {
            string methodName = method.Name;
            int    paramCount = method.GetParameters().Length;

            if (paramCount == 0)
            {
                if (!overridesEquals && methodName == "GetHashCode")
                {
                    return(IdentityEqualityComparer.GetHashCode(proxy));
                }
                else if (IsEqualToIdentifierMethod(method))
                {
                    return(Identifier);
                }
                else if (methodName == "Dispose")
                {
                    return(null);
                }
                else if ("get_HibernateLazyInitializer".Equals(methodName))
                {
                    return(this);
                }
            }
            else if (paramCount == 1)
            {
                if (!overridesEquals && methodName == "Equals")
                {
                    return(IdentityEqualityComparer.Equals(args[0], proxy));
                }
                else if (setIdentifierMethod != null && method.Equals(setIdentifierMethod))
                {
                    Initialize();
                    Identifier = args[0];
                    return(InvokeImplementation);
                }
            }
            else if (paramCount == 2)
            {
                // if the Proxy Engine delegates the call of GetObjectData to the Initializer
                // then we need to handle it.  Castle.DynamicProxy takes care of serializing
                // proxies for us, but other providers might not.
                if (methodName == "GetObjectData")
                {
                    SerializationInfo info    = (SerializationInfo)args[0];
                    StreamingContext  context = (StreamingContext)args[1];                    // not used !?!

                    if (Target == null & Session != null)
                    {
                        EntityKey key    = Session.GenerateEntityKey(Identifier, Session.Factory.GetEntityPersister(EntityName));
                        object    entity = Session.PersistenceContext.GetEntity(key);
                        if (entity != null)
                        {
                            SetImplementation(entity);
                        }
                    }

                    // let the specific ILazyInitializer write its requirements for deserialization
                    // into the stream.
                    AddSerializationInfo(info, context);

                    // don't need a return value for proxy.
                    return(null);
                }
            }

            //if it is a property of an embedded component, invoke on the "identifier"
            if (componentIdType != null && componentIdType.IsMethodOf(method))
            {
                return(method.Invoke(Identifier, args));
            }

            return(InvokeImplementation);
        }