public void Generate() { if (Context.Language == CodeLanguage.VB) { // turn option strict on for VB if in project settings VSProject project = (VSProject) Context.ProjectItem.ContainingProject.Object; Property prop = project.Project.Properties.Item("OptionExplicit"); if ((prjOptionStrict) prop.Value == prjOptionStrict.prjOptionStrictOn) { Context.CompileUnit.UserData.Add("AllowLateBound", false); } } CodeNamespace nameSpace = new CodeNamespace(Context.Namespace); nameSpace.Imports.AddRange(Context.Model.NamespaceImports.ToArray()); Context.CompileUnit.Namespaces.Add(nameSpace); TemplateMemberGenerator templateMemberGenerator = new TemplateMemberGenerator(Context); templateMemberGenerator.AddTemplateUsings(); foreach (ModelClass cls in Context.Model.Classes) { GenerateClass(cls, nameSpace, templateMemberGenerator); } foreach (NestedClass cls in Context.Model.NestedClasses) { GenerateNestedClass(cls, nameSpace); } if (Context.Model.GenerateMetaData != MetaDataGeneration.False) { GenerateMetaData(nameSpace); } GenerateInternalPropertyAccessor(Context, Context.Model, nameSpace); GenerateHelperClass(nameSpace); if (Context.Model.Target == CodeGenerationTarget.ActiveRecord) { Context.PrimaryOutput = GenerateCode(Context.CompileUnit); if (Context.Model.UseNHQG) { try { AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve; Assembly assembly = GenerateARAssembly(Context.CompileUnit, false); UseNHQG(assembly); } finally { AppDomain.CurrentDomain.AssemblyResolve -= AssemblyResolve; } } } else { Type starter = null; Assembly assembly = null; AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(AssemblyResolve); try { _activeRecord = Assembly.Load(Context.Model.ActiveRecordAssemblyName); // Code below means: ActiveRecordStarter.ModelsCreated += new ModelsCreatedDelegate(OnARModelCreated); starter = _activeRecord.GetType("Castle.ActiveRecord.ActiveRecordStarter"); EventInfo eventInfo = starter.GetEvent("ModelsValidated"); if (eventInfo == null) { eventInfo = starter.GetEvent("ModelsCreated"); } Type eventType = eventInfo.EventHandlerType; MethodInfo info = GetType().GetMethod("OnARModelCreated", BindingFlags.Public | BindingFlags.Instance); Delegate del = Delegate.CreateDelegate(eventType, this, info); eventInfo.AddEventHandler(this, del); assembly = GenerateARAssembly(Context.CompileUnit, !Context.Model.UseNHQG); } finally { AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler(AssemblyResolve); } // Code below means: ActiveRecordStarter.Initialize(assembly, new InPlaceConfigurationSource()); Type config = _activeRecord.GetType("Castle.ActiveRecord.Framework.Config.InPlaceConfigurationSource"); object configSource = Activator.CreateInstance(config); try { starter.InvokeMember("ResetInitializationFlag", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, null); starter.InvokeMember("Initialize", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[] { assembly, configSource }); } catch (TargetInvocationException ex) { // Eat config errors if (!ex.InnerException.Message.StartsWith("Could not find configuration for")) throw; } ClearARAttributes(Context.CompileUnit); Context.PrimaryOutput = GenerateCode(Context.CompileUnit); foreach (KeyValuePair<string, string> pair in _nHibernateConfigs) { string path = Path.Combine(Context.ModelFilePath, RemoveNamespaceFromStart(pair.Key) + ".hbm.xml"); using (StreamWriter writer = new StreamWriter(path, false, Encoding.Unicode)) { writer.Write(pair.Value); } AddToProject(path, prjBuildAction.prjBuildActionEmbeddedResource); } if (Context.Model.UseNHQG) { UseNHQG(assembly); } } }
private CodeTypeDeclaration GenerateClass(ModelClass cls, CodeNamespace nameSpace, TemplateMemberGenerator templateMemberGenerator) { if (cls == null) throw new ArgumentNullException("cls", "Class not supplied"); if (nameSpace == null) throw new ArgumentNullException("nameSpace", "Namespace not supplied"); if (String.IsNullOrEmpty(cls.Name)) throw new ArgumentException("Class name cannot be blank", "cls"); CodeTypeDeclaration classDeclaration = GetClassDeclaration(cls, nameSpace); GenerateCommonPrimaryKey(cls, classDeclaration); List<ModelProperty> compositeKeys = new List<ModelProperty>(); // Properties and Fields foreach (ModelProperty property in cls.Properties) { PropertyData propertyData = new PropertyData(property); if (property.KeyType != KeyType.CompositeKey) { AddMemberField(classDeclaration, propertyData); if (property.DebuggerDisplay) classDeclaration.CustomAttributes.Add(propertyData.GetDebuggerDisplayAttribute()); if (property.DefaultMember) classDeclaration.CustomAttributes.Add(propertyData.GetDefaultMemberAttribute()); } else compositeKeys.Add(property); } if (compositeKeys.Count > 0) { CodeTypeDeclaration compositeClass = GetCompositeClassDeclaration(nameSpace, classDeclaration, compositeKeys, cls.DoesImplementINotifyPropertyChanged()); // TODO: All access fields in a composite group assumed to be the same. // We have a model validator for this case but the user may save anyway. // Check if all access fields are the same. CodeMemberField memberField = GetPrivateMemberFieldOfCompositeClass(compositeClass, PropertyAccess.Property); classDeclaration.Members.Add(memberField); classDeclaration.Members.Add(GetActiveRecordMemberCompositeKeyProperty(compositeClass, memberField, cls.DoesImplementINotifyPropertyChanged(), cls.DoesImplementINotifyPropertyChanging())); } //ManyToOne links where this class is the target (1-n) ReadOnlyCollection<ManyToOneRelation> manyToOneSources = ManyToOneRelation.GetLinksToSources(cls); foreach (ManyToOneRelation relationship in manyToOneSources) { GenerateHasManyRelation(classDeclaration, nameSpace, relationship); } //ManyToOne links where this class is the source (n-1) ReadOnlyCollection<ManyToOneRelation> manyToOneTargets = ManyToOneRelation.GetLinksToTargets(cls); foreach (ManyToOneRelation relationship in manyToOneTargets) { GenerateBelongsToRelation(classDeclaration, nameSpace, relationship); } //ManyToMany links where this class is the source ReadOnlyCollection<ManyToManyRelation> manyToManyTargets = ManyToManyRelation.GetLinksToManyToManyTargets(cls); foreach (ManyToManyRelation relationship in manyToManyTargets) { GenerateHasAndBelongsToRelationFromTargets(classDeclaration, nameSpace, relationship); } //ManyToMany links where this class is the target ReadOnlyCollection<ManyToManyRelation> manyToManySources = ManyToManyRelation.GetLinksToManyToManySources(cls); foreach (ManyToManyRelation relationship in manyToManySources) { GenerateHasAndBelongsToRelationFromSources(classDeclaration, nameSpace, relationship); } //OneToOne link where this class is the source OneToOneRelation oneToOneTarget = OneToOneRelation.GetLinkToOneToOneTarget(cls); if (oneToOneTarget != null) { GenerateOneToOneRelationFromTarget(classDeclaration, nameSpace, oneToOneTarget); } //OneToOne links where this class is the target ReadOnlyCollection<OneToOneRelation> oneToOneSources = OneToOneRelation.GetLinksToOneToOneSources(cls); foreach (OneToOneRelation relationship in oneToOneSources) { GenerateOneToOneRelationFromSources(classDeclaration, nameSpace, relationship); } //Nested links ReadOnlyCollection<NestedClassReferencesModelClasses> nestingTargets = NestedClassReferencesModelClasses.GetLinksToNestedClasses(cls); foreach (NestedClassReferencesModelClasses relationship in nestingTargets) { GenerateNestingRelationFromRelationship(classDeclaration, relationship); } // TODO: Other relation types (any etc) GenerateDerivedClass(cls, nameSpace); templateMemberGenerator.AddTemplateMembers(cls, classDeclaration); return classDeclaration; }