public byte[] GenerateCode(string inputFilePath) { using (Store store = new Store(typeof(CoreDesignSurfaceDomainModel), typeof(ConfigurationSectionDesignerDomainModel))) { // Prepare the model ConfigurationSectionModel model = PrepareModel(inputFilePath, store); // Prepare code generator CodeCompileUnit generationUnit = PrepareCodeGenerator(); // Generate code for the configuration elements foreach (BaseConfigurationType type in model.ConfigurationElements) { // Ignore any ConfigurationType that is not an instance of // the ConfigurationElement. ConfigurationElement element = type as ConfigurationElement; if (element == null) { continue; } // Create namespace declaration CodeNamespace elementNamespace = new CodeNamespace(element.ActualNamespace); generationUnit.Namespaces.Add(elementNamespace); // Create the element class and set common options CodeTypeDeclaration elementClass = new CodeTypeDeclaration(element.Name); elementNamespace.Types.Add(elementClass); elementClass.Comments.Add(DocComment("<summary>")); elementClass.Comments.Add(DocComment(EscapeStringChars(element.DocumentationText))); elementClass.Comments.Add(DocComment("</summary>")); elementClass.TypeAttributes = (element.AccessModifier == AccessModifiers.Public) ? TypeAttributes.Public : TypeAttributes.NotPublic; if (element.InheritanceModifier == InheritanceModifiers.Abstract) { elementClass.TypeAttributes |= TypeAttributes.Abstract; } else if (element.InheritanceModifier == InheritanceModifiers.Sealed) { elementClass.TypeAttributes |= TypeAttributes.Sealed; } elementClass.IsPartial = true; elementClass.IsClass = true; if (element.BaseClass != null) { elementClass.BaseTypes.Add(GlobalSelfReference(element.BaseClass.FullName)); } // Set element-type specific options if (element is ConfigurationSection) { // Set base type to be ConfigurationSection if (element.BaseClass == null) { elementClass.BaseTypes.Add(GlobalReference(typeof(System.Configuration.ConfigurationSection))); } // Do custom ConfigurationElementCollection code generation GenerateConfigurationSectionCode(element, elementClass); } else if (element is ConfigurationElementCollection) { // Set base type to be ConfigurationElementCollection if (element.BaseClass == null) { elementClass.BaseTypes.Add(GlobalReference(typeof(System.Configuration.ConfigurationElementCollection))); } // Do custom ConfigurationElementCollection code generation GenerateConfigurationElementCollectionCode(element, elementClass); } else if (element is ConfigurationElement) { // Set base type to be ConfigurationElement if (element.BaseClass == null) { elementClass.BaseTypes.Add(GlobalReference(typeof(System.Configuration.ConfigurationElement))); } } // Set IsReadOnly setting CodeMemberMethod isReadOnlyMethod = new CodeMemberMethod(); elementClass.Members.Add(isReadOnlyMethod); isReadOnlyMethod.StartDirectives.Add(Region("IsReadOnly override")); isReadOnlyMethod.Comments.Add(DocComment("<summary>")); isReadOnlyMethod.Comments.Add(DocComment("Gets a value indicating whether the element is read-only.")); isReadOnlyMethod.Comments.Add(DocComment("</summary>")); isReadOnlyMethod.CustomAttributes.Add(_generatedCodeAttribute); isReadOnlyMethod.Attributes = MemberAttributes.Public | MemberAttributes.Override; isReadOnlyMethod.ReturnType = _bool; isReadOnlyMethod.Name = "IsReadOnly"; isReadOnlyMethod.Statements.Add( new CodeMethodReturnStatement( element.IsReadOnly ? _true : _false ) ); isReadOnlyMethod.EndDirectives.Add(EndRegion()); // Add all the element's properties foreach (ConfigurationProperty property in element.Properties) { GenerateProperty(element, elementClass, property); } if (element.HasCustomChildElements) { GenerateCustomChildElementHandler(elementClass); } } foreach (TypeDefinition type in model.TypeDefinitions) { EnumeratedType enumType = type as EnumeratedType; if (enumType != null && ((enumType.CodeGenOptions & TypeDefinitionCodeGenOptions.TypeDefinition) == TypeDefinitionCodeGenOptions.TypeDefinition)) { // Create the namespace block CodeNamespace typeNamespace = new CodeNamespace(enumType.Namespace); generationUnit.Namespaces.Add(typeNamespace); // Create enum CodeTypeDeclaration enumTypeDeclaration = new CodeTypeDeclaration(enumType.Name); typeNamespace.Types.Add(enumTypeDeclaration); enumTypeDeclaration.Comments.Add(DocComment("<summary>")); if (string.IsNullOrEmpty(enumType.Documentation)) { // If the enum has no documentation, just make the documentation the name of the enum value enumTypeDeclaration.Comments.Add(DocComment(string.Format("{0}.", enumType.Name))); } else { enumTypeDeclaration.Comments.Add(DocComment(EscapeStringChars(enumType.Documentation))); } enumTypeDeclaration.Comments.Add(DocComment("</summary>")); enumTypeDeclaration.CustomAttributes.Add(_generatedCodeAttribute); if (enumType.IsFlags) { enumTypeDeclaration.CustomAttributes.Add(new CodeAttributeDeclaration(GlobalReference(typeof(FlagsAttribute)))); } enumTypeDeclaration.Attributes = MemberAttributes.Public; enumTypeDeclaration.IsEnum = true; foreach (EnumerationLiteral literal in enumType.Literals) { CodeMemberField enumField = new CodeMemberField(); enumTypeDeclaration.Members.Add(enumField); enumField.Comments.Add(DocComment("<summary>")); if (string.IsNullOrEmpty(literal.Documentation)) { enumField.Comments.Add(DocComment(string.Format("{0}.", literal.Name))); } else { enumField.Comments.Add(DocComment(EscapeStringChars(literal.Documentation))); } enumField.Comments.Add(DocComment("</summary>")); enumField.Name = literal.Name; if (!string.IsNullOrEmpty(literal.Value)) { enumField.InitExpression = new CodeSnippetExpression(literal.Value); } } } } if (model.PropertyValidators.Validators.Count > 0) { GenerateValidators(model, generationUnit); } if (model.CustomTypeConverters.Count > 0) { GenerateCustomConverters(model, generationUnit); } _generator.GenerateCodeFromCompileUnit(generationUnit, _codeWriter, _options); _codeWriter.Flush(); byte[] output = new byte[_codeStream.Length]; Array.Copy(_codeStream.GetBuffer(), 0, output, 0, _codeStream.Length); return(output); } }
// [Note by Max 20140906] TODO this should create a new appdomain to import an assembly and then unloading it. // If you load an assembly of the current solution you are not able to build anymore // since msbuild is unable to delete the assembly because is currently in use. private void ImportExternalEnum() { OpenFileDialog ofd = new OpenFileDialog() { DefaultExt = "dll", Filter = "Assemblies (*.dll)|*.dll|All Files (*.*)|*.*" }; if (ofd.ShowDialog() == DialogResult.OK) { string file = ofd.FileName; Assembly assembly = Assembly.LoadFrom(file); List <Type> enumTypes = new List <Type>(); foreach (Type type in assembly.GetExportedTypes()) { if (type.IsEnum) { enumTypes.Add(type); } } if (enumTypes.Count == 0) { MessageBox.Show("The chosen assembly has no public Enums.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } ConfigurationSectionDesignerDiagram diagram = this.SingleDocumentSelection as ConfigurationSectionDesignerDiagram; using (Transaction transaction = diagram.Store.TransactionManager.BeginTransaction("Import External Enum")) { using (ImportEnumForm importEnumForm = new ImportEnumForm(enumTypes)) { if (importEnumForm.ShowDialog() == DialogResult.OK) { ConfigurationSectionModel model = diagram.ModelElement as ConfigurationSectionModel; Type enumType = importEnumForm.SelectedEnum; FlagsAttribute fa = enumType.GetCustomAttributes(false) .Where(a => a is FlagsAttribute) .SingleOrDefault() as FlagsAttribute; EnumeratedType enumeratedType = new EnumeratedType(diagram.Store); enumeratedType.CodeGenOptions = TypeDefinitionCodeGenOptions.None; enumeratedType.Name = enumType.Name; enumeratedType.Namespace = enumType.Namespace; enumeratedType.IsFlags = fa != null; FieldInfo[] fields = enumType.GetFields(BindingFlags.Public | BindingFlags.Static); foreach (FieldInfo field in fields) { EnumerationLiteral enumeratedLiteral = new EnumerationLiteral(diagram.Store); enumeratedLiteral.Name = field.Name; enumeratedType.Literals.Add(enumeratedLiteral); } model.TypeDefinitions.Add(enumeratedType); transaction.Commit(); } else { transaction.Rollback(); } } } } }