Ejemplo n.º 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="componentClass"></param>
        /// <param name="propertyNames"></param>
        /// <param name="propertyGetters"></param>
        /// <param name="propertySetters"></param>
        /// <param name="foundCustomAcessor"></param>
        /// <param name="propertyTypes"></param>
        /// <param name="joinedFetch"></param>
        /// <param name="cascade"></param>
        /// <param name="parentProperty"></param>
        public ComponentType(System.Type componentClass,
                             string[] propertyNames,
                             IGetter[] propertyGetters,
                             ISetter[] propertySetters,
                             // currently not used, see the comment near the end of the method body
                             bool foundCustomAcessor,
                             IType[] propertyTypes,
                             OuterJoinFetchStrategy[] joinedFetch,
                             Cascades.CascadeStyle[] cascade,
                             string parentProperty)
        {
            this.componentClass = componentClass;
            this.propertyTypes  = propertyTypes;
            propertySpan        = propertyNames.Length;
            getters             = propertyGetters;
            setters             = propertySetters;
            string[]      getterNames = new string[propertySpan];
            string[]      setterNames = new string[propertySpan];
            System.Type[] propTypes   = new System.Type[propertySpan];
            for (int i = 0; i < propertySpan; i++)
            {
                getterNames[i] = getters[i].PropertyName;
                setterNames[i] = setters[i].PropertyName;
                propTypes[i]   = getters[i].ReturnType;
            }

            if (parentProperty == null)
            {
                parentSetter = null;
                parentGetter = null;
            }
            else
            {
                IPropertyAccessor pa = PropertyAccessorFactory.GetPropertyAccessor(null);
                parentSetter = pa.GetSetter(componentClass, parentProperty);
                parentGetter = pa.GetGetter(componentClass, parentProperty);
            }
            this.propertyNames = propertyNames;
            this.cascade       = cascade;
            this.joinedFetch   = joinedFetch;

            // NH: reflection optimizer works with custom accessors
            if (/*!foundCustomAcessor &&*/ Cfg.Environment.UseReflectionOptimizer)
            {
                this.getset = GetSetHelperFactory.Create(componentClass, setters, getters);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Build the generated code
        /// </summary>
        /// <param name="code">Generated code</param>
        /// <returns>An instance of the generated class</returns>
        private IGetSetHelper Build(string code)
        {
            CodeDomProvider provider = new CSharpCodeProvider();

#if NET_2_0
            CompilerResults res = provider.CompileAssemblyFromSource(cp, new string[] { code });
#else
            ICodeCompiler   compiler = provider.CreateCompiler();
            CompilerResults res      = compiler.CompileAssemblyFromSource(cp, code);
#endif

            if (res.Errors.HasErrors)
            {
                log.Debug("Compiled with error:\n" + code);
                foreach (CompilerError e in res.Errors)
                {
                    log.Debug(
                        String.Format("Line:{0}, Column:{1} Message:{2}",
                                      e.Line, e.Column, e.ErrorText)
                        );
                }
                throw new InvalidOperationException(res.Errors[0].ErrorText);
            }
            else
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("Compiled ok:\n" + code);
                }
            }

            Assembly      assembly = res.CompiledAssembly;
            System.Type[] types    = assembly.GetTypes();
            IGetSetHelper getset   = ( IGetSetHelper )assembly.CreateInstance(types[0].FullName, false,
                                                                              BindingFlags.CreateInstance, null, new object[] { setters, getters },
                                                                              CultureInfo.InvariantCulture, null);

            return(getset);
        }
		/// <summary>
		/// 
		/// </summary>
		/// <param name="componentClass"></param>
		/// <param name="propertyNames"></param>
		/// <param name="propertyGetters"></param>
		/// <param name="propertySetters"></param>
		/// <param name="foundCustomAcessor"></param>
		/// <param name="propertyTypes"></param>
		/// <param name="joinedFetch"></param>
		/// <param name="cascade"></param>
		/// <param name="parentProperty"></param>
		public ComponentType( System.Type componentClass,
		                      string[ ] propertyNames,
		                      IGetter[ ] propertyGetters,
		                      ISetter[ ] propertySetters,
		                      // currently not used, see the comment near the end of the method body
							  bool foundCustomAcessor,
		                      IType[ ] propertyTypes,
		                      OuterJoinFetchStrategy[ ] joinedFetch,
		                      Cascades.CascadeStyle[ ] cascade,
		                      string parentProperty)
		{
			this.componentClass = componentClass;
			this.propertyTypes = propertyTypes;
			propertySpan = propertyNames.Length;
			getters = propertyGetters;
			setters = propertySetters;
			string[ ] getterNames = new string[propertySpan];
			string[ ] setterNames = new string[propertySpan];
			System.Type[ ] propTypes = new System.Type[propertySpan];
			for( int i = 0; i < propertySpan; i++ )
			{
				getterNames[ i ] = getters[ i ].PropertyName;
				setterNames[ i ] = setters[ i ].PropertyName;
				propTypes[ i ] = getters[ i ].ReturnType;
			}

			if( parentProperty == null )
			{
				parentSetter = null;
				parentGetter = null;
			}
			else
			{
				IPropertyAccessor pa = PropertyAccessorFactory.GetPropertyAccessor( null );
				parentSetter = pa.GetSetter( componentClass, parentProperty );
				parentGetter = pa.GetGetter( componentClass, parentProperty );
			}
			this.propertyNames = propertyNames;
			this.cascade = cascade;
			this.joinedFetch = joinedFetch;

			// NH: reflection optimizer works with custom accessors
			if( /*!foundCustomAcessor &&*/ Cfg.Environment.UseReflectionOptimizer )
			{
				this.getset = GetSetHelperFactory.Create(componentClass, setters, getters);
			}
		}
		protected AbstractEntityPersister( PersistentClass model, ISessionFactoryImplementor factory )
		{
			dialect = factory.Dialect;
			//sqlExceptionConverter = factory.SQLExceptionConverter;

			// CLASS
			className = model.MappedClass.FullName;
			rootClassName = model.RootClazz.Name;
			mappedClass = model.MappedClass;

			mutable = model.IsMutable;
			selectBeforeUpdate = model.SelectBeforeUpdate;
			dynamicUpdate = model.DynamicUpdate;
			dynamicInsert = model.DynamicInsert;
			sqlWhereString = model.Where;
			sqlWhereStringTemplate = sqlWhereString == null ?
				null :
				Template.RenderWhereStringTemplate( sqlWhereString, Dialect );

			polymorphic = model.IsPolymorphic;
			explicitPolymorphism = model.IsExplicitPolymorphism;
			inherited = model.IsInherited;
			superclass = inherited ? model.Superclass.MappedClass : null;
			hasSubclasses = model.HasSubclasses;

			batchSize = model.BatchSize;

			constructor = ReflectHelper.GetDefaultConstructor( mappedClass );
			abstractClass = ReflectHelper.IsAbstractClass( mappedClass );

			entityType = NHibernateUtil.Entity( mappedClass );

			optimisticLockMode = model.OptimisticLockMode;
			if( optimisticLockMode > OptimisticLockMode.Version && !dynamicUpdate )
			{
				throw new MappingException( string.Format( "optimistic-lock setting requires dynamic-update=\'true\': {0}", className ) );
			}

			// verify that the class has a default constructor if it is not abstract - it is considered
			// a mapping exception if the default ctor is missing.
			if( abstractClass == false && constructor == null )
			{
				throw new MappingException( "The mapped class " + mappedClass.FullName + " must declare a default (no-arg) constructor." );
			}

			// IDENTIFIER
			hasEmbeddedIdentifier = model.HasEmbeddedIdentifier;
			IValue idValue = model.Identifier;
			identifierType = idValue.Type;

			if( model.HasIdentifierProperty )
			{
				Mapping.Property idProperty = model.IdentifierProperty;
				identifierPropertyName = idProperty.Name;
				identifierSetter = idProperty.GetSetter( mappedClass );
				identifierGetter = idProperty.GetGetter( mappedClass );
			}
			else
			{
				identifierPropertyName = null;
				identifierGetter = null;
				identifierSetter = null;
			}

			System.Type prox = model.ProxyInterface;
			MethodInfo proxySetIdentifierMethod = null;
			MethodInfo proxyGetIdentifierMethod = null;

			if( model.HasIdentifierProperty && prox != null )
			{
				Mapping.Property idProperty = model.IdentifierProperty;

				PropertyInfo getIdPropertyInfo = idProperty.GetGetter( prox ).Property;

				if( getIdPropertyInfo != null )
				{
					proxyGetIdentifierMethod = getIdPropertyInfo.GetGetMethod( true );
				}

				PropertyInfo setIdPropertyInfo = idProperty.GetSetter( prox ).Property;

				if( setIdPropertyInfo != null )
				{
					proxySetIdentifierMethod = setIdPropertyInfo.GetSetMethod( true );
				}
			}

			// HYDRATE SPAN
			hydrateSpan = model.PropertyClosureCollection.Count;

			// IDENTIFIER 
			int idColumnSpan = model.Identifier.ColumnSpan;
			identifierColumnNames = new string[idColumnSpan];
			identifierAliases = new string[idColumnSpan];

			int i = 0;
			foreach( Column col in idValue.ColumnCollection )
			{
				identifierColumnNames[ i ] = col.GetQuotedName( Dialect );
				identifierAliases[ i ] = col.Alias( Dialect );
				i++;
			}

			// GENERATOR
			identifierGenerator = model.Identifier.CreateIdentifierGenerator( Dialect );
			useIdentityColumn = identifierGenerator is IdentityGenerator;
			identitySelectString = useIdentityColumn ? dialect.IdentitySelectString : null;

			// UNSAVED-VALUE:
			unsavedIdentifierValue = UnsavedValueFactory.GetUnsavedIdentifierValue(
				model.Identifier.NullValue,
				identifierGetter,
				identifierType,
				constructor );

			// VERSION:

			if( model.IsVersioned )
			{
				foreach( Column col in model.Version.ColumnCollection )
				{
					versionColumnName = col.GetQuotedName( Dialect );
					break; //only happens once
				}
			}
			else
			{
				versionColumnName = null;
			}

			if( model.IsVersioned )
			{
				//versionPropertyName = model.Version.Name;
				versioned = true;
				versionGetter = model.Version.GetGetter( mappedClass );
				versionType = ( IVersionType ) model.Version.Type;
			}
			else
			{
				//versionPropertyName = null;
				versioned = false;
				versionGetter = null;
				versionType = null;
			}

			// VERSION UNSAVED-VALUE:
			unsavedVersionValue = model.IsVersioned ?
				UnsavedValueFactory.GetUnsavedVersionValue(
					model.Version.NullValue,
					versionGetter,
					versionType,
					constructor ) :
				Cascades.VersionValue.VersionUndefined;

			// PROPERTIES 

			propertyTypes = new IType[hydrateSpan];
			propertyNames = new string[hydrateSpan];
			propertyUpdateability = new bool[hydrateSpan];
			propertyInsertability = new bool[hydrateSpan];
			propertyNullability = new bool[hydrateSpan];
			getters = new IGetter[hydrateSpan];
			setters = new ISetter[hydrateSpan];
			cascadeStyles = new Cascades.CascadeStyle[hydrateSpan];
			string[ ] setterNames = new string[hydrateSpan];
			string[ ] getterNames = new string[hydrateSpan];
			System.Type[ ] types = new System.Type[hydrateSpan];

			i = 0;
			int tempVersionProperty = -66;
			bool foundCascade = false;
			
			bool foundCustomAccessor = false;

			foreach( Mapping.Property prop in model.PropertyClosureCollection )
			{
				if( prop == model.Version )
				{
					tempVersionProperty = i;
				}
				propertyNames[ i ] = prop.Name;
				if( !prop.IsBasicPropertyAccessor )
				{
					foundCustomAccessor = true;
				}

				getters[ i ] = prop.GetGetter( mappedClass );
				setters[ i ] = prop.GetSetter( mappedClass );
				getterNames[ i ] = getters[ i ].PropertyName;
				setterNames[ i ] = setters[ i ].PropertyName;
				types[ i ] = getters[ i ].ReturnType;
				propertyTypes[ i ] = prop.Type;
				propertyUpdateability[ i ] = prop.IsUpdateable;
				propertyInsertability[ i ] = prop.IsInsertable;
				propertyNullability[ i ] = prop.IsNullable;

				gettersByPropertyName[ propertyNames[ i ] ] = getters[ i ];
				settersByPropertyName[ propertyNames[ i ] ] = setters[ i ];
				typesByPropertyName[ propertyNames[ i ] ] = propertyTypes[ i ];

				cascadeStyles[ i ] = prop.CascadeStyle;
				if( cascadeStyles[ i ] != Cascades.CascadeStyle.StyleNone )
				{
					foundCascade = true;
				}

				i++;
			}

			// NH: reflection optimizer works with custom accessors
			if( /*!foundCustomAccessor &&*/ Cfg.Environment.UseReflectionOptimizer )
			{
				getset = GetSetHelperFactory.Create( MappedClass, Setters, Getters );
			}

			hasCascades = foundCascade;
			versionProperty = tempVersionProperty;

			// CALLBACK INTERFACES
			implementsLifecycle = typeof( ILifecycle ).IsAssignableFrom( mappedClass );
			implementsValidatable = typeof( IValidatable ).IsAssignableFrom( mappedClass );

			cache = model.Cache;

			hasCollections = InitHasCollections();

			// PROXIES
			concreteProxyClass = model.ProxyInterface;
			hasProxy = concreteProxyClass != null;

			if( hasProxy )
			{
				HashedSet proxyInterfaces = new HashedSet();
				proxyInterfaces.Add( typeof( INHibernateProxy ) );

				if( !mappedClass.Equals( concreteProxyClass ) )
				{
					if( !concreteProxyClass.IsInterface )
					{
						throw new MappingException(
							"proxy must be either an interface, or the class itself: " +
								mappedClass.FullName );
					}

					proxyInterfaces.Add( concreteProxyClass );
				}

				if( mappedClass.IsInterface )
				{
					proxyInterfaces.Add( mappedClass );
				}

				if( hasProxy )
				{
					foreach( Subclass subclass in model.SubclassCollection )
					{
						System.Type subclassProxy = subclass.ProxyInterface;
						if( subclassProxy == null )
						{
							throw new MappingException( "All subclasses must also have proxies: "
								+ mappedClass.Name );
						}

						if( !subclass.MappedClass.Equals( subclassProxy ) )
						{
							proxyInterfaces.Add( subclassProxy );
						}
					}
				}

				if( hasProxy )
				{
					proxyFactory = CreateProxyFactory();
					proxyFactory.PostInstantiate( mappedClass, proxyInterfaces, proxyGetIdentifierMethod, proxySetIdentifierMethod );
				}
				else
				{
					proxyFactory = null;
				}
			}
			else
			{
				proxyFactory = null;
			}
		}