Example #1
0
        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();
                        }
                    }
                }
            }
        }