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); } }
/// <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); }