public MetadataProviderService(IMetadataProviderService defaultService, IDictionary<string, string> paramters)
        {
            MakeReadonlyFieldsEditable = ConfigHelper.GetAppSettingOrDefault("MakeReadonlyFieldsEditable", false);
            Metadata = defaultService.LoadMetadata();
            var prop = typeof(AttributeMetadata).GetProperty("IsValidForCreate", BindingFlags.Public | BindingFlags.Instance);
            foreach (var att in Metadata.Entities.SelectMany(entity => entity.Attributes)) {
                switch (att.LogicalName)
                {
                    case "modifiedonbehalfby":
                    case "createdonbehalfby":
                    case "overriddencreatedon":
                            
                        prop.SetValue(att, true);
                        break;

                    case "createdby":
                    case "createdon":
                    case "modifiedby":
                    case "modifiedon":
                    case "owningbusinessunit":
                    case "owningteam":
                    case "owninguser":
                        if (MakeReadonlyFieldsEditable)
                        {
                            prop.SetValue(att, true);
                        }
                        break;
                }
            }
        }
Exemplo n.º 2
0
        public MetadataService(IMetadataProviderService defaultMetadataService)
        {
#if DEBUG
            if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(Constants.ENVIRONMENT_ATTACHDEBUGGER)))
            {
                System.Diagnostics.Debugger.Launch();
            }
#endif

            if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(Constants.ENVIRONMENT_CACHEMEATADATA)))
            {
                Console.WriteLine(Constants.CONSOLE_METADATA);

                var manager = new RecyclableMemoryStreamManager();
                using (var stream = manager.GetStream())
                {
                    using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true))
                    {
                        string line = Console.ReadLine();
                        while (line != Constants.CONSOLE_ENDSTREAM && line != null)
                        {
                            writer.WriteLine(line);
                            line = Console.ReadLine();
                        }
                    }
                    stream.Position = 0;
                    var serializer = new DataContractSerializer(typeof(OrganizationMetadata));
                    using (var xmlreader = XmlReader.Create(stream, new XmlReaderSettings()))
                    {
                        cachedMetadata = (OrganizationMetadata)serializer.ReadObject(xmlreader);
                    }
                }
            }
            this.defaultMetadataService = defaultMetadataService;
        }
        protected virtual void WriteInternal(IOrganizationMetadata organizationMetadata, string language, string outputFile, string targetNamespace, IServiceProvider services)
        {
            if (UseTfsToCheckoutFiles)
            {
                Log("Getting TFS Workspace for file " + outputFile);
                var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(outputFile);
                var server        = new TfsTeamProjectCollection(workspaceInfo.ServerUri);
                TfsWorkspace = workspaceInfo.GetWorkspace(server);
                Log("TFS Workspace {0}found!", TfsWorkspace == null ? "not " : string.Empty);
            }

            EnsureFileIsAccessible(outputFile);

            Log("Creating Temp file");
            var tempFile = Path.GetTempFileName();

            Log("File " + tempFile + " Created");

            // Write the file out as normal
            Log("Writing file {0} to {1}", Path.GetFileName(outputFile), tempFile);
            _defaultService.Write(organizationMetadata, language, tempFile, targetNamespace, services);
            Log("Completed writing file {0} to {1}", Path.GetFileName(outputFile), tempFile);

            // Check if the Header needs to be updated and or the file needs to be split
            if (!string.IsNullOrWhiteSpace(CommandLineText) || RemoveRuntimeVersionComment)
            {
                var lines = GetFileTextWithUpdatedClassComment(tempFile, CommandLineText, RemoveRuntimeVersionComment);
                if (CreateOneFilePerCodeUnit)
                {
                    SplitFileByCodeUnit(SplitByCodeUnit, outputFile, lines);
                }
                else
                {
                    Log("Updating file " + outputFile);
                    File.WriteAllLines(outputFile, lines);
                    if (UndoCheckoutIfUnchanged(outputFile))
                    {
                        Console.WriteLine(outputFile + " was unchanged.");
                    }
                }
            }
            else if (CreateOneFilePerCodeUnit)
            {
                SplitFileByCodeUnit(SplitByCodeUnit, outputFile, File.ReadAllLines(tempFile));
            }
            else
            {
                File.Copy(tempFile, outputFile);
                if (UndoCheckoutIfUnchanged(outputFile))
                {
                    Console.WriteLine(outputFile + " was unchanged.");
                }
            }

            Log("Cleaning up Temporary File " + tempFile);
            File.Delete(tempFile);
            Log("Completed cleaning up Temporary File");

            Console.WriteLine(tempFile + " Moved To: " + outputFile);
        }
Exemplo n.º 4
0
        public void Write(IOrganizationMetadata organizationMetadata, string language, string outputFile, string targetNamespace, IServiceProvider services)
        {
            // Since the CodeGenerationSerivce has lots of static internal methdos - we have to use reflecion to call them

            var           crmsvcCodeGenerationService = Type.GetType("Microsoft.Crm.Services.Utility.CodeGenerationService,CrmSvcUtil");
            var           BuildCodeDom = crmsvcCodeGenerationService.GetMethod("BuildCodeDom", BindingFlags.Static | BindingFlags.NonPublic);
            CodeNamespace codeDom      = (CodeNamespace)BuildCodeDom.Invoke(null, new object[] { organizationMetadata, targetNamespace, services });

            HashSet <string>           typeNames  = new HashSet <string>();
            List <CodeTypeDeclaration> duplicates = new List <CodeTypeDeclaration>();

            // Remove duplicate global optionsets
            foreach (CodeTypeDeclaration item in codeDom.Types)
            {
                if (typeNames.Contains(item.Name))
                {
                    duplicates.Add(item);
                }
                else
                {
                    typeNames.Add(item.Name);
                }
            }

            foreach (CodeTypeDeclaration duplicate in duplicates)
            {
                codeDom.Types.Remove(duplicate);
            }

            var WriteFile = crmsvcCodeGenerationService.GetMethod("WriteFile", BindingFlags.Static | BindingFlags.NonPublic);

            WriteFile.Invoke(null, new object[] { outputFile, language, codeDom, services });
        }
Exemplo n.º 5
0
        public void Write(IOrganizationMetadata organizationMetadata, string language, string outputFile, string targetNamespace, IServiceProvider services)
        {
            var entityName = SingleEntityConfiguration.Instance.GetEntityAlternateName();

            codeGenerationService.Write(organizationMetadata, language, $"{entityName}.cs", targetNamespace, services);
            SingleEntityHelper.Instance.WriteToFile($"{entityName}.cs", $"{entityName}_new.cs");
        }
        public MetadataProviderService(IMetadataProviderService defaultService, IDictionary <string, string> paramters)
        {
            MakeReadonlyFieldsEditable = ConfigHelper.GetAppSettingOrDefault("MakeReadonlyFieldsEditable", false);
            Metadata = defaultService.LoadMetadata();
            var prop = typeof(AttributeMetadata).GetProperty("IsValidForCreate", BindingFlags.Public | BindingFlags.Instance);

            foreach (var att in Metadata.Entities.SelectMany(entity => entity.Attributes))
            {
                switch (att.LogicalName)
                {
                case "modifiedonbehalfby":
                case "createdonbehalfby":
                case "overriddencreatedon":

                    prop.SetValue(att, true);
                    break;

                case "createdby":
                case "createdon":
                case "modifiedby":
                case "modifiedon":
                case "owningbusinessunit":
                case "owningteam":
                case "owninguser":
                    if (MakeReadonlyFieldsEditable)
                    {
                        prop.SetValue(att, true);
                    }
                    break;
                }
            }
        }
Exemplo n.º 7
0
 void ICodeGenerationService.Write(IOrganizationMetadata organizationMetadata, string language, string outputFile, string outputNamespace, IServiceProvider services)
 {
     Trace.TraceInformation("Entering {0}", new object[] {MethodBase.GetCurrentMethod().Name});
     var serviceProvider = services as ServiceProvider;
     var codenamespace = BuildCodeDom(organizationMetadata, outputNamespace, serviceProvider);
     WriteFile(outputFile, language, codenamespace, serviceProvider);
     Trace.TraceInformation("Exiting {0}", new object[] {MethodBase.GetCurrentMethod().Name});
 }
Exemplo n.º 8
0
 public IOrganizationMetadata LoadMetadata()
 {
     if (cachedMetadata == null)
     {
         cachedMetadata = defaultMetadataService.LoadMetadata();
     }
     return(cachedMetadata);
 }
        private async Task WriteCodeAsync(IOrganizationMetadata organizationMetadata)
        {
            await this._methodTracer.EnterAsync();

            await this.ServiceProvider.CodeGenerationService.WriteAsync(organizationMetadata, this.Parameters.Language, this.Parameters.OutputFile, this.Parameters.Namespace, this.ServiceProvider);

            await this._methodTracer.ExitAsync();
        }
Exemplo n.º 10
0
 protected override void WriteInternal(IOrganizationMetadata organizationMetadata, string language, string outputFile, string targetNamespace, IServiceProvider services)
 {
     base.WriteInternal(organizationMetadata, language, outputFile, targetNamespace, services);
     // Since no Actions.cs class gets created by default, they are all request / response classes, delete the file if there is no CommandLineText to be added
     if (!CreateOneFilePerCodeUnit && string.IsNullOrEmpty(CommandLineText))
     {
         File.Delete(outputFile);
     }
 }
 protected override void WriteInternal(IOrganizationMetadata organizationMetadata, string language, string outputFile, string targetNamespace, IServiceProvider services)
 {
     base.WriteInternal(organizationMetadata, language, outputFile, targetNamespace, services);
     // Since no Actions.cs class gets created by default, they are all request / response classes, delete the file if there is no CommandLineText to be added
     if (!CreateOneFilePerCodeUnit && string.IsNullOrEmpty(CommandLineText))
     {
         File.Delete(outputFile);
     }
 }
Exemplo n.º 12
0
 public Provider(string fileName)
 {
     var startupPath = AppDomain.CurrentDomain.BaseDirectory;
     var pathItems = startupPath.Split(Path.DirectorySeparatorChar);
     var projectPath = string.Join(Path.DirectorySeparatorChar.ToString(), pathItems.Take(pathItems.Length - 2));
     var path = Path.Combine(projectPath, "Metadata", fileName);
     UnzipMetadata(path);
     _metadata = MetadataProviderService.DeserializeMetadata(path);
 }
Exemplo n.º 13
0
        public Provider(string fileName)
        {
            var startupPath = AppDomain.CurrentDomain.BaseDirectory;
            var pathItems   = startupPath.Split(Path.DirectorySeparatorChar);
            var projectPath = string.Join(Path.DirectorySeparatorChar.ToString(), pathItems.Take(pathItems.Length - 2));
            var path        = Path.Combine(projectPath, "Metadata", fileName);

            UnzipMetadata(path);
            _metadata = MetadataProviderService.DeserializeMetadata(path);
        }
Exemplo n.º 14
0
 public void Write(IOrganizationMetadata organizationMetadata, string language, string outputFile, string outputNamespace, IServiceProvider services)
 {
     try
     {
         WriteInternal(organizationMetadata, language, Path.GetFullPath(outputFile), outputNamespace, services);
     }
     catch (Exception ex)
     {
         Console.WriteLine(ex.ToString());
     }
 }
Exemplo n.º 15
0
        public void TestInitialise()
        {
            typeof(SolutionHelper)
            .NullStaticField(nameof(SolutionHelper.organisationService))
            .NullStaticField(nameof(SolutionHelper.solutionEntities))
            .NullStaticField(nameof(SolutionHelper.commandlineArgs));

            organizationMetadata = Substitute.For <IOrganizationMetadata>();
            orgService           = Substitute.For <IOrganizationService>();
            SolutionHelper.organisationService = orgService;
        }
 public void Write(IOrganizationMetadata organizationMetadata, string language, string outputFile, string targetNamespace, IServiceProvider services)
 {
     try
     {
         WriteInternal(organizationMetadata, language, outputFile, targetNamespace, services);
     }
     catch (Exception ex)
     {
         Console.WriteLine(ex.ToString());
     }
 }
Exemplo n.º 17
0
        protected override void WriteInternal(IOrganizationMetadata organizationMetadata, string language, string outputFile, string targetNamespace, IServiceProvider services)
        {
            OutputFilePath = outputFile;

            base.WriteInternal(organizationMetadata, language, outputFile, targetNamespace, services);

            // Since no Actions.cs class gets created by default, they are all request / response classes, delete the file if there is no CommandLineText to be added
            if (ShouldDeleteMainFile())
            {
                File.Delete(outputFile);
            }
        }
        public static void SerializeMetadata(IOrganizationMetadata metadata, string filePath)
        {
            var localMetadata = new Metadata
            {
                Entities   = metadata.Entities,
                OptionSets = metadata.OptionSets,
                Messages   = metadata.Messages
            };

            filePath = RootPath(filePath);
            File.WriteAllText(filePath, Serialize(localMetadata, true));
        }
Exemplo n.º 19
0
        public void CustomizeCodeDom(CodeCompileUnit codeCompileUnit, IServiceProvider services)
        {
            if (codeCompileUnit == null)
            {
                throw new ArgumentNullException(nameof(codeCompileUnit));
            }
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            Console.WriteLine(string.Empty);
            Console.WriteLine("Generating code is in progress.");

            ReferencedOptionSetNames = new List <string>();

            ICodeWriterFilterService codeWriterFilterService = (ICodeWriterFilterService)services.GetService(typeof(ICodeWriterFilterService));
            IMetadataProviderService metadataProviderService = (IMetadataProviderService)services.GetService(typeof(IMetadataProviderService));
            IOrganizationMetadata    organizationMetadata    = metadataProviderService.LoadMetadata();

            // ServiceHelper.IntersectionEntityList = organizationMetadata.Entities.Where(x => x.IsIntersect == true).ToList();

            foreach (CodeNamespace codeNamespace in codeCompileUnit.Namespaces)
            {
                foreach (EntityInfo entityInfo in ServiceHelper.EntityList)
                {
                    EntityMetadata entityMetadata = entityInfo.EntityMetadata;

                    CodeTypeDeclaration codeTypeDeclaration = codeNamespace
                                                              .Types
                                                              .OfType <CodeTypeDeclaration>()
                                                              .FirstOrDefault(codeType => codeType.Name.ToUpperInvariant() == entityMetadata.SchemaName.ToUpperInvariant());

                    GenerateMultiSelectOptionSets(codeNamespace, codeTypeDeclaration, entityMetadata);

                    GenerateOptionSets(codeNamespace, codeTypeDeclaration, entityMetadata);

                    GenerateSetterForReadOnlyFields(codeTypeDeclaration, entityMetadata);
                }
            }

            ExcludeNonReferencedGlobalOptionSets(codeCompileUnit, organizationMetadata);

            GenerateFieldStructures(codeCompileUnit);

            GenerateCodeFiles(codeCompileUnit);

            CleanupNamespaces(codeCompileUnit);

            Console.WriteLine("Generating code completed successfully.");
        }
        private static void SerializeMetadataToFile(IOrganizationMetadata metadata, string filePath)
        {
            var localMetadata = new Metadata
            {
                Entities   = metadata.Entities,
                OptionSets = metadata.OptionSets,
                Messages   = metadata.Messages
            };

            filePath = RootPath(filePath);
            var serialized = Serializer.SerializeJsonDc(localMetadata);

            File.WriteAllText(filePath, serialized);
        }
Exemplo n.º 21
0
 IOrganizationMetadata IMetadataProviderService.LoadMetadata()
 {
     if (_organizationMetadata == null)
     {
         using (var proxy = CreateOrganizationServiceEndpoint())
         {
             proxy.Timeout = new TimeSpan(0, 5, 0);
             var entityMetadata = RetrieveEntities(proxy);
             var optionSetMetadata = RetrieveOptionSets(proxy);
             var messages = RetrieveSdkRequests(proxy);
             _organizationMetadata = CreateOrganizationMetadata(entityMetadata, optionSetMetadata, messages);
         }
     }
     return _organizationMetadata;
 }
        public void CustomizeCodeDom(CodeCompileUnit codeUnit, IServiceProvider services)
        {
            var metadataProviderService    = (IMetadataProviderService)services.GetService(typeof(IMetadataProviderService));
            IOrganizationMetadata metadata = metadataProviderService.LoadMetadata();

            foreach (CodeNamespace codeNamespace in codeUnit.Namespaces)
            {
                foreach (CodeTypeDeclaration codeTypeDeclaration in codeNamespace.Types)
                {
                    if (codeTypeDeclaration.IsClass)
                    {
                        foreach (EntityMetadata entityMetadata in metadata.Entities.Where(e => e.SchemaName == codeTypeDeclaration.Name))
                        {
                            foreach (CodeTypeMember codeTypeMember in codeTypeDeclaration.Members)
                            {
                                if (codeTypeMember.GetType() == typeof(System.CodeDom.CodeMemberProperty) && codeTypeMember.CustomAttributes.Count > 0 && codeTypeMember.CustomAttributes[0].AttributeType.BaseType == "Microsoft.Xrm.Sdk.AttributeLogicalNameAttribute")
                                {
                                    AttributeMetadata attributeMetadata = entityMetadata.Attributes.Where(a => a.LogicalName == ((System.CodeDom.CodePrimitiveExpression)codeTypeMember.CustomAttributes[0].Arguments[0].Value).Value.ToString()).FirstOrDefault();

                                    if (attributeMetadata != null)
                                    {
                                        string label       = (attributeMetadata.DisplayName.UserLocalizedLabel == null ? attributeMetadata.LogicalName : (attributeMetadata.DisplayName.UserLocalizedLabel.Label ?? attributeMetadata.LogicalName));
                                        string description = (attributeMetadata.Description.UserLocalizedLabel == null ? "None" : (attributeMetadata.Description.UserLocalizedLabel.Label ?? "None"));

                                        codeTypeMember.CustomAttributes.Add(new CodeAttributeDeclaration {
                                            Name = "System.ComponentModel.Description", Arguments = { new CodeAttributeArgument {
                                                                                                          Value = new CodePrimitiveExpression(label)
                                                                                                      } }
                                        });

                                        if (codeTypeMember.Comments != null)
                                        {
                                            for (int i = 0; i < codeTypeMember.Comments.Count - 1; i++)
                                            {
                                                if (codeTypeMember.Comments[i].Comment.Text.ToLowerInvariant() == "<summary>")
                                                {
                                                    codeTypeMember.Comments[i + 1].Comment.Text = string.Format("{0}: {1}", label, description);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 23
0
        public static IOrganizationMetadata LoadMetadata(this IServiceProvider services)
        {
            if (SolutionHelper.services == null)
            {
                SolutionHelper.services = services;
            }

            if (organisationMetadata != null)
            {
                return(organisationMetadata);
            }

            "IMetadataProviderService.LoadMetadata Start".Debug();

            var metadataProviderService = (IMetadataProviderService)services.GetService(typeof(IMetadataProviderService));

            organisationMetadata = metadataProviderService.LoadMetadata();

            "IMetadataProviderService.LoadMetadata End".Debug();

            return(organisationMetadata);
        }
        public OptionSetEnumHandler(CodeCompileUnit codeUnit, IServiceProvider services, bool removePropertyChanged, bool generateXmlDocumentation)
        {
            this.codeUnit = codeUnit;
            var metadataProvider = (IMetadataProviderService)services.GetService(typeof(IMetadataProviderService));

            this.organizationMetadata = metadataProvider.LoadMetadata();
            var entities = new HashSet <string>((Environment.GetEnvironmentVariable(Constants.ENVIRONMENT_ENTITIES) ?? "").Split(","));

            allAttributes    = new HashSet <string>((Environment.GetEnvironmentVariable(Constants.ENVIRONMENT_ALL_ATTRIBUTES) ?? "").Split(","));
            entityAttributes = new Dictionary <string, HashSet <string> >();
            foreach (var entity in entities.Except(allAttributes))
            {
                entityAttributes.Add(entity, new HashSet <string>((Environment.GetEnvironmentVariable(string.Format(CultureInfo.InvariantCulture, Constants.ENVIRONMENT_ENTITY_ATTRIBUTES, entity)) ?? "").Split(",")));
            }
            TwoOptionsEnum                = (Environment.GetEnvironmentVariable(Constants.ENVIRONMENT_TWOOPTIONS) ?? "") == "1";
            TwoOptionsConstants           = (Environment.GetEnvironmentVariable(Constants.ENVIRONMENT_TWOOPTIONS) ?? "") == "2";
            OptionSetEnumProperties       = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable(Constants.ENVIRONMENT_OPTIONSETENUMPROPERTIES));
            OptionSetEnumProperties       = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable(Constants.ENVIRONMENT_OPTIONSETENUMPROPERTIES));
            CrmSvcUtilsVersion            = FileVersionInfo.GetVersionInfo(typeof(SdkMessage).Assembly.Location).FileVersion;
            CrmSvcUtilsName               = typeof(SdkMessage).Assembly.GetName().Name;
            this.removePropertyChanged    = removePropertyChanged;
            this.generateXmlDocumentation = generateXmlDocumentation;
        }
Exemplo n.º 25
0
        protected virtual void WriteInternal(IOrganizationMetadata organizationMetadata, string language, string outputFile, string targetNamespace, IServiceProvider services)
        {
            Metadata        = organizationMetadata;
            ServiceProvider = services;
            if (UseTfsToCheckoutFiles)
            {
                Tfs = new VsTfsSourceControlProvider(null, new ProcessExecutorInfo
                {
                    OnOutputReceived = Log,
                    OnErrorReceived  = DisplayMessage
                });
            }
            DisplayMessage("Ensuring Context File is Accessible");
            EnsureFileIsAccessible(outputFile);

            Log("Creating Temp file");
            var tempFile = Path.GetTempFileName();

            Log("File " + tempFile + " Created");

            // Write the file out as normal
            DisplayMessage($"Writing file {Path.GetFileName(outputFile)} to {tempFile}");
            DefaultService.Write(organizationMetadata, language, tempFile, targetNamespace, services);
            Log("Completed writing file {0} to {1}", Path.GetFileName(outputFile), tempFile);

            // Check if the Header needs to be updated and or the file needs to be split
            if (!string.IsNullOrWhiteSpace(CommandLineText) || RemoveRuntimeVersionComment)
            {
                var lines = GetFileTextWithUpdatedClassComment(tempFile, CommandLineText, RemoveRuntimeVersionComment);
                if (CreateOneFilePerCodeUnit)
                {
                    DisplayMessage($"Splitting File {outputFile} By Code Unit");
                    SplitFileByCodeUnit(SplitByCodeUnit, outputFile, lines);
                }
                else
                {
                    DisplayMessage($"Updating File {outputFile}");
                    File.WriteAllLines(outputFile, lines);
                    if (UndoCheckoutIfUnchanged(outputFile))
                    {
                        Console.WriteLine(outputFile + " was unchanged.");
                    }
                }
            }
            else if (CreateOneFilePerCodeUnit)
            {
                DisplayMessage($"Splitting File {outputFile} By Code Unit");
                SplitFileByCodeUnit(SplitByCodeUnit, outputFile, File.ReadAllLines(tempFile));
            }
            else
            {
                DisplayMessage($"Copying File {outputFile}");
                File.Copy(tempFile, outputFile, true);
                if (UndoCheckoutIfUnchanged(outputFile))
                {
                    Console.WriteLine(outputFile + " was unchanged.");
                }
            }

            DisplayMessage($"Cleaning up Temporary File {tempFile}");
            File.Delete(tempFile);
            Log("Completed cleaning up Temporary File");
            DisplayMessage(tempFile + " Moved To: " + outputFile);
        }
Exemplo n.º 26
0
        private void ExcludeNonReferencedGlobalOptionSets(CodeCompileUnit codeCompileUnit, IOrganizationMetadata organizationMetadata)
        {
            if (codeCompileUnit == null)
            {
                throw new ArgumentNullException(nameof(codeCompileUnit));
            }
            if (organizationMetadata == null)
            {
                throw new ArgumentNullException(nameof(organizationMetadata));
            }

            if (!Properties.Settings.Default.GenerateOnlyReferencedGlobalOptionSets)
            {
                return;
            }

            Console.WriteLine(string.Empty);
            Console.WriteLine("Excluding non referenced option sets.");

            foreach (OptionSetMetadataBase optionSetMetadata in organizationMetadata.OptionSets)
            {
                if (ReferencedOptionSetNames.Contains(optionSetMetadata.Name))
                {
                    continue;
                }

                foreach (CodeNamespace codeNamespace in codeCompileUnit.Namespaces)
                {
                    CodeTypeDeclaration codeTypeDeclaration = codeNamespace
                                                              .Types.OfType <CodeTypeDeclaration>()
                                                              .FirstOrDefault(codeType => codeType.Name.ToUpperInvariant() == optionSetMetadata.Name.ToUpperInvariant());

                    if (codeTypeDeclaration == null)
                    {
                        continue;
                    }

                    codeNamespace.Types.Remove(codeTypeDeclaration);
                }
            }
        }
Exemplo n.º 27
0
        public void CustomizeCodeDom(CodeCompileUnit codeCompileUnit, IServiceProvider services)
        {
            Services         = services;
            metadata         = services.LoadMetadata();
            filteringService = (ICodeWriterFilterService)services.GetService(typeof(ICodeWriterFilterService));
            namingService    = (INamingService)services.GetService(typeof(INamingService));

            Console.WriteLine($"Customise {DateTime.Now}");

            var codeNamespace = codeCompileUnit.Namespaces[0];
            var imports       = codeNamespace.Imports;

            imports.AddRange(new[] {
                new CodeNamespaceImport {
                    Namespace = "System"
                },
                new CodeNamespaceImport {
                    Namespace = "System.Linq"
                },
                new CodeNamespaceImport {
                    Namespace = "Microsoft.Xrm.Sdk"
                },
                new CodeNamespaceImport {
                    Namespace = "System.Runtime.Serialization"
                },
                new CodeNamespaceImport {
                    Namespace = "Microsoft.Xrm.Sdk.Client"
                },
                new CodeNamespaceImport {
                    Namespace = "System.Collections.Generic"
                },
                new CodeNamespaceImport {
                    Namespace = "System.ComponentModel"
                },
                new CodeNamespaceImport {
                    Namespace = "System.Diagnostics.CodeAnalysis"
                }
            });

            foreach (var entityMetadata in metadata.Entities)
            {
                var entityClass = codeNamespace.Types.Cast <CodeTypeDeclaration>().FirstOrDefault(x => GetAttributeValues <EntityLogicalNameAttribute>(x.CustomAttributes)
                                                                                                  ?.FirstOrDefault() == entityMetadata.LogicalName);
                if (entityClass == null)
                {
                    continue;
                }

                var interfaceCodeType = new CodeTypeDeclaration
                {
                    Name        = "I" + entityClass.Name,
                    IsPartial   = true,
                    IsInterface = true
                };

                entityClass.Comments.Clear();
                entityClass.BaseTypes.Clear();
                entityClass.BaseTypes.Add(new CodeTypeReference("EarlyEntity"));
                entityClass.CustomAttributes.Add(new CodeAttributeDeclaration("ExcludeFromCodeCoverage"));

                for (var i = entityClass.Members.Count - 1; i >= 0; i--)
                {
                    var codeTypeMember  = entityClass.Members[i];
                    var codeConstructor = codeTypeMember as CodeConstructor;
                    if (codeConstructor != null)
                    {
                        codeConstructor.Comments.Clear();
                        continue;
                    }

                    var codeMethod = codeTypeMember as CodeMemberMethod;
                    if (codeMethod != null)
                    {
                        if (codeMethod.Name == "OnPropertyChanging" || codeMethod.Name == "OnPropertyChanged")
                        {
                            entityClass.Members.RemoveAt(i);
                        }
                        continue;
                    }

                    var codeEvent = codeTypeMember as CodeMemberEvent;
                    if (codeEvent != null)
                    {
                        entityClass.Members.RemoveAt(i);
                        continue;
                    }

                    var codeMemberField = codeTypeMember as CodeMemberField;
                    if (codeMemberField != null)
                    {
                        if (codeMemberField.Name == "EntityTypeCode")
                        {
                            entityClass.Members.RemoveAt(i);
                        }
                        continue;
                    }

                    var codeMemberProperty = codeTypeMember as CodeMemberProperty;
                    if (codeMemberProperty == null)
                    {
                        continue;
                    }

                    if (entityMetadata.IsIntersect == true)
                    {
                        var relationshipSchema = GetAttributeValues <RelationshipSchemaNameAttribute>(codeMemberProperty.CustomAttributes)?.FirstOrDefault();
                        if (relationshipSchema != null && entityMetadata.ManyToManyRelationships.Any(x => x.SchemaName == relationshipSchema))
                        {
                            entityClass.Members.RemoveAt(i);
                        }
                    }

                    codeMemberProperty.Comments.Clear();

                    foreach (CodeAttributeDeclaration att in codeTypeMember.CustomAttributes)
                    {
                        att.Name = att.Name.Replace("Microsoft.Xrm.Sdk.", "");
                    }

                    codeTypeMember.Comments.Clear();

                    var type = codeMemberProperty.Type;

                    if (type.BaseType == "System.Guid")
                    {
                        codeMemberProperty.Type = new CodeTypeReference("Guid");
                    }
                    if (type.BaseType.StartsWith("Microsoft.Xrm.Sdk."))
                    {
                        codeMemberProperty.Type = new CodeTypeReference(codeMemberProperty.Type.BaseType.Replace("Microsoft.Xrm.Sdk.", ""));
                    }
                    if (type.BaseType.StartsWith(codeNamespace.Name + "."))
                    {
                        codeMemberProperty.Type = new CodeTypeReference(codeMemberProperty.Type.BaseType.Replace(codeNamespace.Name + ".", ""));
                    }

                    if (type.BaseType.StartsWith("System.Nullable`1"))
                    {
                        if (type.TypeArguments[0].BaseType == "System.Int32")
                        {
                            codeMemberProperty.Type = new CodeTypeReference("int?");
                        }
                        if (type.TypeArguments[0].BaseType == "System.Int64")
                        {
                            codeMemberProperty.Type = new CodeTypeReference("long?");
                        }
                        if (type.TypeArguments[0].BaseType == "System.Boolean")
                        {
                            codeMemberProperty.Type = new CodeTypeReference("bool?");
                        }
                        if (type.TypeArguments[0].BaseType == "System.DateTime")
                        {
                            codeMemberProperty.Type = new CodeTypeReference("DateTime?");
                        }
                        if (type.TypeArguments[0].BaseType == "System.Double")
                        {
                            codeMemberProperty.Type = new CodeTypeReference("double?");
                        }
                        if (type.TypeArguments[0].BaseType == "System.Decimal")
                        {
                            codeMemberProperty.Type = new CodeTypeReference("decimal?");
                        }
                        if (type.TypeArguments[0].BaseType == "System.Guid")
                        {
                            codeMemberProperty.Type = new CodeTypeReference("Guid?");
                            var attributeLogicalNameAttribute = codeMemberProperty.CustomAttributes.Cast <CodeAttributeDeclaration>().FirstOrDefault(x => x.Name.EndsWith("AttributeLogicalNameAttribute"));
                            if (attributeLogicalNameAttribute != null)
                            {
                                var ctr         = attributeLogicalNameAttribute.Arguments.Cast <CodeAttributeArgument>().First().Value as CodePrimitiveExpression;
                                var logicalName = ctr.Value.ToString();
                                var att         = entityMetadata.Attributes.FirstOrDefault(x => x.LogicalName == logicalName);
                                if (att.IsPrimaryId == true)
                                {
                                    entityClass.Members.RemoveAt(i);
                                    continue;
                                }
                            }
                        }
                    }

                    if (type.BaseType.StartsWith("System.Collections.Generic."))
                    {
                        if (type.TypeArguments[0].BaseType.StartsWith("Microsoft.Xrm.Sdk."))
                        {
                            codeMemberProperty.Type = new CodeTypeReference(type.BaseType.Replace("System.Collections.Generic.", ""),
                                                                            new CodeTypeReference(type.TypeArguments[0].BaseType.Replace("Microsoft.Xrm.Sdk.", "")));
                        }
                    }

                    if (type.BaseType.StartsWith("System.Collections.Generic.IEnumerable"))
                    {
                        var baseType = type.TypeArguments[0].BaseType.Replace(codeNamespace.Name + ".", "");
                        codeMemberProperty.Type = new CodeTypeReference(type.BaseType.Replace("System.Collections.Generic.", ""), new CodeTypeReference($"{baseType}"));
                    }
                }

                var props = entityClass.Members.Cast <CodeTypeMember>().OfType <CodeMemberProperty>().ToList();

                for (var index = props.Count() - 1; index >= 0; index--)
                {
                    var prop = props[index];

                    var logicalName        = GetAttributeValues <AttributeLogicalNameAttribute>(prop.CustomAttributes)?.FirstOrDefault();
                    var relationshipSchema = GetAttributeValues <RelationshipSchemaNameAttribute>(prop.CustomAttributes)?.FirstOrDefault();

                    if (logicalName != null && relationshipSchema == null)
                    {
                        if (entityMetadata.Attributes == null)
                        {
                            continue;
                        }

                        var propertyLogicalName = GetAttributeValues <AttributeLogicalNameAttribute>(prop.CustomAttributes).First();
                        var enumAtt             = entityMetadata.Attributes.FirstOrDefault(x => x.LogicalName == propertyLogicalName &&
                                                                                           new[] { AttributeTypeCode.Picklist, AttributeTypeCode.Status, AttributeTypeCode.State, AttributeTypeCode.Virtual, AttributeTypeCode.EntityName }.Any(y => y == x.AttributeType)) as EnumAttributeMetadata;

                        if (enumAtt != null && enumAtt.OptionSet != null)
                        {
                            var optionsSetName = namingService.GetNameForOptionSet(entityMetadata, enumAtt.OptionSet, services);
                            var enumDef        = codeNamespace.Types.Cast <CodeTypeDeclaration>().FirstOrDefault(x => x.IsEnum && x.Name == optionsSetName);

                            if (enumDef == null) // probably only used by a multi-picklist, for some reason they don't get generated!
                            {
                                var codeTypeDeclaration = new CodeTypeDeclaration
                                {
                                    IsEnum = true,
                                    Name   = optionsSetName,
                                };

                                codeTypeDeclaration.Members.AddRange(enumAtt.OptionSet.Options
                                                                     .Select(x =>
                                                                             new CodeMemberField
                                {
                                    CustomAttributes =
                                    {
                                        new CodeAttributeDeclaration("EnumMember")
                                    },
                                    InitExpression = new CodePrimitiveExpression(x.Value),
                                    Name           = x.Label.DisplayName()
                                }
                                                                             ).ToArray());

                                codeNamespace.Types.Add(codeTypeDeclaration);

                                enumDef = codeTypeDeclaration;
                            }

                            CleanEnum(enumDef, enumAtt, entityClass.Name);

                            if (UseDisplayNames && NestNonGlobalEnums && enumAtt.OptionSet.IsGlobal == false)
                            {
                                optionsSetName = $"Enums.{optionsSetName.Substring(entityClass.Name.Length + 1)}";
                            }

                            prop.GetStatements.Clear();

                            if (enumAtt as MultiSelectPicklistAttributeMetadata != null)
                            {
                                prop.Type = new CodeTypeReference($"IEnumerable<{optionsSetName}>");

                                prop.GetStatements.Add(new CodeSnippetStatement($"{tabs}return GetAttributeEnums<{optionsSetName}>(\"{enumAtt.LogicalName}\");"));
                                if (prop.HasSet || AddSetters)
                                {
                                    prop.SetStatements.Clear();
                                    prop.SetStatements.AddRange(new[] {
                                        new CodeSnippetStatement($"{tabs}SetAttributeEnums(\"{logicalName}\", nameof({prop.Name}), value);"),
                                    });
                                }
                            }
                            else
                            {
                                prop.Type = new CodeTypeReference(optionsSetName + "?");

                                prop.GetStatements.Add(new CodeSnippetStatement($"{tabs}return ({optionsSetName}?)GetAttributeValue<OptionSetValue>(\"{enumAtt.LogicalName}\")?.Value;"));
                                if (prop.HasSet || AddSetters)
                                {
                                    prop.SetStatements.Clear();
                                    prop.SetStatements.AddRange(new[] {
                                        new CodeSnippetStatement($"{tabs}SetAttributeValue(\"{logicalName}\", nameof({prop.Name}), value.HasValue ? new OptionSetValue((int)value.Value) : null);"),
                                    });
                                }
                            }

                            continue;
                        }

                        var baseType = prop.Type.BaseType;
                        baseType = baseType.Replace("System.Byte", "byte");
                        baseType = baseType.Replace("System.String", "string");

                        if (prop.Type.TypeArguments.Count > 0)
                        {
                            baseType = baseType.Replace("`1", "<" + prop.Type.TypeArguments[0].BaseType + ">");
                        }

                        if (prop.Type.ArrayRank != 0)
                        {
                            baseType += "[]";
                        }

                        prop.GetStatements.Clear();

                        var method = "AttributeValue";
                        if (prop.Type.BaseType.StartsWith("IEnumerable"))
                        {
                            method += "s";
                        }

                        if (prop.Name == "Id")
                        {
                            prop.Attributes = MemberAttributes.New | MemberAttributes.Public;
                            prop.GetStatements.Add(new CodeSnippetStatement($"{tabs}return base.Id != default ? base.Id : Get{method}<{baseType}>(\"{logicalName}\");"));
                        }
                        else
                        {
                            var genericType = prop.Type.TypeArguments.Count > 0 ? prop.Type.TypeArguments[0].BaseType : baseType;
                            prop.GetStatements.Add(new CodeSnippetStatement($"{tabs}return Get{method}<{genericType}>(\"{logicalName}\");"));
                        }

                        if (prop.HasSet || AddSetters)
                        {
                            prop.SetStatements.Clear();
                            prop.SetStatements.Add(new CodeSnippetStatement($"{tabs}Set{method}(\"{logicalName}\", nameof({prop.Name}), value);"));

                            if (prop.Name == "Id")
                            {
                                prop.SetStatements.Add(new CodeSnippetStatement($"{tabs}base.Id = value;"));
                            }
                        }

                        continue;
                    }

                    var codeAttributes = GetCodeAttributeArguments <RelationshipSchemaNameAttribute>(prop.CustomAttributes);

                    string entityRole = string.Empty;
                    if (codeAttributes != null && codeAttributes.Count() > 1)
                    {
                        var erAttribute = codeAttributes.Skip(1).First();
                        var role        = erAttribute.Value as CodeFieldReferenceExpression;
                        entityRole        = $", EntityRole.{role.FieldName}";
                        erAttribute.Value = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("EntityRole"), role.FieldName);
                    }

                    if (logicalName == null && relationshipSchema != null)
                    {
                        var m2mRelationship = entityMetadata.ManyToManyRelationships.FirstOrDefault(x => x.SchemaName == relationshipSchema);

                        if (m2mRelationship != null)
                        {
                            var m2mEnt   = metadata.Entities.FirstOrDefault(x => x.LogicalName == m2mRelationship.IntersectEntityName);
                            var generate = filteringService.GenerateEntity(m2mEnt, services);

                            if (generate)
                            {
                                var type = UseDisplayNames ? m2mEnt.DisplayName() : m2mEnt.SchemaName;
                                if (string.IsNullOrEmpty(type))
                                {
                                    type = m2mEnt.SchemaName;
                                }

                                prop.CustomAttributes.Insert(0, new CodeAttributeDeclaration("AttributeProvider", new CodeAttributeArgument(new CodeTypeOfExpression(type))));
                            }
                        }

                        var baseType = prop.Type.TypeArguments[0].BaseType.Replace(codeNamespace.Name + ".", "");

                        prop.Type = new CodeTypeReference(prop.Type.BaseType.Replace("System.Collections.Generic.", ""), new CodeTypeReference($"{baseType}"));
                        prop.GetStatements.Clear();
                        prop.GetStatements.Add(new CodeSnippetStatement($"{tabs}return GetRelatedEntities<{baseType}>(\"{relationshipSchema}\"{entityRole});"));

                        if (prop.HasSet)
                        {
                            prop.SetStatements.Clear();
                            prop.SetStatements.Add(new CodeSnippetStatement($"{tabs}SetRelatedEntities<{baseType}>(\"{relationshipSchema}\", nameof({prop.Name}), value{entityRole});"));
                        }

                        continue;
                    }

                    if (logicalName != null && relationshipSchema != null)
                    {
                        var baseType = prop.Type.BaseType.Replace(codeNamespace.Name + ".", "");
                        prop.Type = new CodeTypeReference(baseType);
                        prop.GetStatements.Clear();
                        prop.GetStatements.Add(new CodeSnippetStatement($"{tabs}return GetRelatedEntity<{baseType}>(\"{relationshipSchema}\"{entityRole});"));

                        if (prop.HasSet)
                        {
                            prop.SetStatements.Clear();
                            prop.SetStatements.Add(new CodeSnippetStatement($"{tabs}SetRelatedEntity<{baseType}>(\"{relationshipSchema}\", nameof({prop.Name}), value{entityRole});"));
                        }

                        continue;
                    }
                }
            }

            foreach (CodeNamespace ns in codeCompileUnit.Namespaces)
            {
                foreach (CodeTypeDeclaration type in ns.Types)
                {
                    for (var i = type.CustomAttributes.Count - 1; i >= 0; i--)
                    {
                        var catt = type.CustomAttributes[i];
                        catt.Name = catt.Name.Replace("System.Runtime.Serialization.", "").Replace("DataContractAttribute", "DataContract");
                        catt.Name = catt.Name.Replace("Microsoft.Xrm.Sdk.Client.", "");
                        if (catt.Name.Contains("GeneratedCodeAttribute"))
                        {
                            type.CustomAttributes.RemoveAt(i);
                        }
                    }
                }
            }

            // re-order alphabetical
            for (var i = 0; i < codeCompileUnit.Namespaces.Count; ++i)
            {
                var types = codeCompileUnit.Namespaces[i].Types.Cast <CodeTypeDeclaration>().ToList();

                for (var j = 0; j < types.Count; ++j)
                {
                    var membersCopy = new CodeTypeMember[types[j].Members.Count];
                    types[j].Members.CopyTo(membersCopy, 0);
                    var orderedMembers = membersCopy.OrderBy(x => x.Name).ToArray();

                    types[j].Members.Clear();
                    types[j].Members.AddRange(orderedMembers);
                }

                var typesCopy = new CodeTypeDeclaration[codeCompileUnit.Namespaces[i].Types.Count];
                codeCompileUnit.Namespaces[i].Types.CopyTo(typesCopy, 0);
                var orderedTypes = typesCopy.OrderBy(x => x.Name).ToArray();

                for (var j = 0; j < codeCompileUnit.Namespaces[i].Types.Count;)
                {
                    codeCompileUnit.Namespaces[i].Types.RemoveAt(j);
                }

                codeCompileUnit.Namespaces[i].Types.AddRange(orderedTypes);
            }

            if (UseDisplayNames && NestNonGlobalEnums)
            {
                for (var i = 0; i < codeCompileUnit.Namespaces.Count; ++i)
                {
                    var classes = codeCompileUnit.Namespaces[i].Types;

                    for (var j = classes.Count - 1; j >= 0; j--)
                    {
                        var type = classes[j];

                        if (type.IsEnum)
                        {
                            var parent = classes.Cast <CodeTypeDeclaration>().FirstOrDefault(x => x.IsClass && type.Name.StartsWith(x.Name + "_", StringComparison.OrdinalIgnoreCase));

                            if (parent != null)
                            {
                                var isProbablyGlobal = metadata.OptionSets.Any(x => x.DisplayName.DisplayName() == type.Name);
                                if (isProbablyGlobal)
                                {
                                    continue;
                                }

                                var enums = parent.Members.Cast <CodeTypeMember>().FirstOrDefault(x => x.Name == "Enums") as CodeTypeDeclaration;
                                if (enums == null)
                                {
                                    enums = new CodeTypeDeclaration("Enums")
                                    {
                                        IsStruct = true, CustomAttributes = { new CodeAttributeDeclaration("DataContract") }
                                    };
                                    parent.Members.Add(enums);
                                }

                                type.Name = type.Name.Substring(parent.Name.Length + 1);

                                enums.Members.Add(type);

                                classes.Remove(type);
                            }
                        }
                    }
                }
            }

            if (GenerateConstants)
            {
                for (var i = 0; i < codeCompileUnit.Namespaces.Count; ++i)
                {
                    var classes = codeCompileUnit.Namespaces[i].Types;

                    foreach (var type in classes.Cast <CodeTypeDeclaration>())
                    {
                        if (type.IsClass)
                        {
                            var logicalNames = new CodeTypeDeclaration("LogicalNames")
                            {
                                IsStruct = true, CustomAttributes = { new CodeAttributeDeclaration("DataContract") }
                            };
                            type.Members.Add(logicalNames);

                            var relationships = new CodeTypeDeclaration("Relationships")
                            {
                                IsStruct = true, CustomAttributes = { new CodeAttributeDeclaration("DataContract") }
                            };
                            type.Members.Add(relationships);

                            var props = type.Members.Cast <CodeTypeMember>().OfType <CodeMemberProperty>();
                            foreach (var prop in props)
                            {
                                var logicalName        = GetAttributeValues <AttributeLogicalNameAttribute>(prop.CustomAttributes)?.FirstOrDefault();
                                var relationshipSchema = GetAttributeValues <RelationshipSchemaNameAttribute>(prop.CustomAttributes)?.FirstOrDefault();

                                if (logicalName != null && relationshipSchema == null)
                                {
                                    logicalNames.Members.Add(new CodeSnippetTypeMember($"{new string('\t', 3)}public const string {prop.Name} = \"{logicalName}\";"));
                                }

                                if (relationshipSchema != null)
                                {
                                    relationships.Members.Add(new CodeSnippetTypeMember($"{new string('\t', 3)}public const string {prop.Name} = \"{relationshipSchema}\";"));
                                }
                            }
                        }
                    }
                }
            }

            var tab     = new string('\t', 1);
            var twoTabs = new string('\t', 2);

            var codeType = new CodeTypeDeclaration("EarlyEntity")
            {
                TypeAttributes   = TypeAttributes.Abstract | TypeAttributes.Public,
                CustomAttributes =
                {
                    new CodeAttributeDeclaration("DataContract"),
                    new CodeAttributeDeclaration("ExcludeFromCodeCoverage")
                }
            };

            codeType.BaseTypes.AddRange(new[] {
                new CodeTypeReference("Entity"),
                new CodeTypeReference("INotifyPropertyChanging"),
                new CodeTypeReference("INotifyPropertyChanged"),
            });

            codeType.Members.Add(new CodeSnippetTypeMember(twoTabs +
                                                           @"public EarlyEntity(string entityLogicalName) : base(entityLogicalName) { }"));

            codeType.Members.AddRange(new[] {
                new CodeSnippetTypeMember(twoTabs +
                                          @"public event PropertyChangedEventHandler PropertyChanged;"),
                new CodeSnippetTypeMember(twoTabs +
                                          @"public event PropertyChangingEventHandler PropertyChanging;"),
                new CodeSnippetTypeMember(twoTabs +
                                          @"protected void OnPropertyChanged(string propertyName)
		{
			if ((PropertyChanged != null))
			{
				PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
			}
		}"        ),
                new CodeSnippetTypeMember(twoTabs +
                                          @"protected void OnPropertyChanging(string propertyName)
		{
			if ((PropertyChanging != null))
			{
				PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
			}
		}"        )
            });

            codeType.Members.AddRange(new[] {
                new CodeSnippetTypeMember(twoTabs +
                                          @"public IEnumerable<T> GetAttributeValues<T>(string attributeLogicalName) where T : Entity
		{
			return base.GetAttributeValue<EntityCollection>(attributeLogicalName)?.Entities?.Cast<T>();
		}"        ),
                new CodeSnippetTypeMember(twoTabs +
                                          @"public IEnumerable<T> GetAttributeEnums<T>(string attributeLogicalName) where T : struct, IConvertible
		{
			return base.GetAttributeValue<OptionSetValueCollection>(attributeLogicalName)?.Select(x => (T)(object)x.Value);
		}"        ),
                new CodeSnippetTypeMember(twoTabs +
                                          @"protected void SetAttributeValues<T>(string logicalName, string attributePropertyName, IEnumerable<T> value)  where T : Entity
		{
			SetAttributeValue(logicalName, attributePropertyName, new EntityCollection(new List<Entity>(value)));
		}"        ),
                new CodeSnippetTypeMember(twoTabs +
                                          @"protected void SetAttributeEnums<T>(string logicalName, string attributePropertyName, IEnumerable<T> value)  where T : struct, IConvertible
		{
			SetAttributeValue(logicalName, attributePropertyName, new OptionSetValueCollection(new List<OptionSetValue>(value.Select(x => new OptionSetValue((int)(object)x)))));
		}"        ),
                new CodeSnippetTypeMember(twoTabs +
                                          @"protected void SetAttributeValue(string logicalName, string attributePropertyName, object value)
		{
			OnPropertyChanging(attributePropertyName);
			base.SetAttributeValue(logicalName, value);
			OnPropertyChanged(attributePropertyName);
		}"        ),
                new CodeSnippetTypeMember(twoTabs +
                                          @"protected new T GetRelatedEntity<T>(string relationshipSchemaName, EntityRole? primaryEntityRole = null) where T : Entity
		{
			return base.GetRelatedEntity<T>(relationshipSchemaName, primaryEntityRole);
		}"        ),
                new CodeSnippetTypeMember(twoTabs +
                                          @"protected void SetRelatedEntity<T>(string relationshipSchemaName, string attributePropertyName, T entity, EntityRole? primaryEntityRole = null) where T : Entity
		{
			OnPropertyChanging(attributePropertyName);
			base.SetRelatedEntity(relationshipSchemaName, primaryEntityRole, entity);
			OnPropertyChanged(attributePropertyName);
		}"        ),
                new CodeSnippetTypeMember(twoTabs +
                                          @"protected new IEnumerable<T> GetRelatedEntities<T>(string relationshipSchemaName, EntityRole? primaryEntityRole = null) where T : Entity
		{
			return base.GetRelatedEntities<T>(relationshipSchemaName, primaryEntityRole);
		}"        ),
                new CodeSnippetTypeMember(twoTabs +
                                          @"protected void SetRelatedEntities<T>(string relationshipSchemaName, string attributePropertyName, IEnumerable<T> entities, EntityRole? primaryEntityRole = null) where T : Entity
		{
			OnPropertyChanging(attributePropertyName);
			base.SetRelatedEntities(relationshipSchemaName, primaryEntityRole, entities);
			OnPropertyChanged(attributePropertyName);
		}"        ),
            });
            codeNamespace.Types.Add(codeType);
        }
        protected virtual void WriteInternal(IOrganizationMetadata organizationMetadata, string language, string outputFile, string targetNamespace, IServiceProvider services)
        {
            if (UseTfsToCheckoutFiles)
            {
                var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(outputFile);
                var server = new TfsTeamProjectCollection(workspaceInfo.ServerUri);
                TfsWorkspace = workspaceInfo.GetWorkspace(server);
            }

            EnsureFileIsAccessible(outputFile);

            Log("Creating Temp file");
            var tempFile = Path.GetTempFileName();
            Log("File " + tempFile + " Created");
            
            // Write the file out as normal
            Log("Writing file {0} to {1}", Path.GetFileName(outputFile), tempFile);
            _defaultService.Write(organizationMetadata, language, tempFile, targetNamespace, services);
            Log("Completed writing file {0} to {1}", Path.GetFileName(outputFile), tempFile);

            // Check if the Header needs to be updated and or the file needs to be split
            if (!String.IsNullOrWhiteSpace(CommandLineText) || RemoveRuntimeVersionComment)
            {
                var lines = GetFileTextWithUpdatedClassComment(tempFile, CommandLineText, RemoveRuntimeVersionComment);
                if (CreateOneFilePerCodeUnit)
                {
                    SplitFileByCodeUnit(SplitByCodeUnit, outputFile, lines);
                }
                else
                {
                    Log("Updating file " + outputFile);
                    File.WriteAllLines(outputFile, lines);
                    if (UndoCheckoutIfUnchanged(outputFile))
                    {
                        Console.WriteLine(outputFile + " was unchanged.");
                    }
                }
            }
            else if (CreateOneFilePerCodeUnit)
            {
                SplitFileByCodeUnit(SplitByCodeUnit, outputFile, File.ReadAllLines(tempFile));
            }
            else
            {
                File.Copy(tempFile, outputFile);
                if (UndoCheckoutIfUnchanged(outputFile))
                {
                    Console.WriteLine(outputFile + " was unchanged.");
                }
            }

            Log("Cleaning up Temporary File " + tempFile);
            File.Delete(tempFile);
            Log("Completed cleaning up Temporary File");

            Console.WriteLine(tempFile + " Moved To: " + outputFile);
        }
Exemplo n.º 29
0
 static CodeNamespace BuildCodeDom(IOrganizationMetadata organizationMetadata, string outputNamespace, ServiceProvider serviceProvider)
 {
     Trace.TraceInformation("Entering {0}", new object[] {MethodBase.GetCurrentMethod().Name});
     var namespace2 = Namespace(outputNamespace);
     namespace2.Types.AddRange(BuildOptionSets(organizationMetadata.OptionSets, serviceProvider));
     namespace2.Types.AddRange(BuildEntities(organizationMetadata.Entities, serviceProvider));
     namespace2.Types.AddRange(BuildServiceContext(organizationMetadata.Entities, serviceProvider));
     namespace2.Types.AddRange(BuildMessages(organizationMetadata.Messages, serviceProvider));
     Trace.TraceInformation("Exiting {0}", new object[] {MethodBase.GetCurrentMethod().Name});
     return namespace2;
 }
        private void AddEntityConsts(CodeCompileUnit codeUnit, string ns, Dictionary <string, Model.Entity> entities, IOrganizationMetadata meta)
        {
            foreach (CodeNamespace n in codeUnit.Namespaces)
            {
                if (n.Name == ns)
                {
                    foreach (CodeTypeDeclaration type in n.Types)
                    {
                        if (type.IsClass)
                        {
                            var logicalNameAttribute = type.CustomAttributes.Cast <CodeAttributeDeclaration>()
                                                       .FirstOrDefault(a => a.Name == "Microsoft.Xrm.Sdk.Client.EntityLogicalNameAttribute");

                            if (logicalNameAttribute == null)
                            {
                                continue;
                            }

                            var typeEntityName = ((CodePrimitiveExpression)logicalNameAttribute.Arguments[0].Value).Value.ToString();

                            if (entities.Values.Where(r => r.LogicalName == typeEntityName).Any())
                            {
                                var entity = new { Type = type, Metadata = meta.Entities.Where(r => r.LogicalName == typeEntityName).Single() };

                                #region decorate entity properties
                                foreach (CodeTypeMember member in type.Members)
                                {
                                    if (member is CodeMemberProperty prop)
                                    {
                                        var logicalAttributeName = prop.CustomAttributes.Cast <CodeAttributeDeclaration>()
                                                                   .FirstOrDefault(a => a.Name == $"Microsoft.Xrm.Sdk.AttributeLogicalNameAttribute");

                                        if (logicalAttributeName == null)
                                        {
                                            continue;
                                        }

                                        prop.Attributes = MemberAttributes.Public | MemberAttributes.Final;

                                        if (prop.Name == "Id")
                                        {
                                            prop.Attributes = MemberAttributes.Public | MemberAttributes.Override;
                                        }

                                        var typeAttributeName = ((CodePrimitiveExpression)logicalAttributeName.Arguments[0].Value).Value.ToString();

                                        var attr = entity.Metadata.Attributes.Where(r => r.LogicalName == typeAttributeName).SingleOrDefault();
                                        if (attr != null)
                                        {
                                            var attrDesc = attr.Description?.UserLocalizedLabel?.Label;
                                            if (!string.IsNullOrEmpty(attrDesc) && attrDesc.Contains(obsoleteName))
                                            {
                                                member.CustomAttributes.Insert(0, new CodeAttributeDeclaration("System.ObsoleteAttribute"));
                                            }

                                            if (attr is StringAttributeMetadata sMeta && sMeta.MaxLength != null && sMeta.MaxLength.Value > 0)
                                            {
                                                member.CustomAttributes.Insert(1, new CodeAttributeDeclaration("Kipon.Xrm.Attributes.Metadata.MaxLengthAttribute", new CodeAttributeArgument(new CodePrimitiveExpression(sMeta.MaxLength.Value))));
                                            }

                                            if (attr is Microsoft.Xrm.Sdk.Metadata.IntegerAttributeMetadata iMeta && iMeta.MinValue != null && iMeta.MaxValue != null)
                                            {
                                                member.CustomAttributes.Insert(1, new CodeAttributeDeclaration(
                                                                                   "Kipon.Xrm.Attributes.Metadata.WholenumberAttribute",
                                                                                   new CodeAttributeArgument(new CodePrimitiveExpression(iMeta.MinValue.Value)),
                                                                                   new CodeAttributeArgument(new CodePrimitiveExpression(iMeta.MaxValue.Value))
                                                                                   ));
                                            }
                                        }
                                    }
                                }
                                #endregion



                                var label = entity.Metadata.Description?.UserLocalizedLabel?.Label;

                                if (!string.IsNullOrEmpty(label) && label.ToLower().Contains(obsoleteName))
                                {
                                    entity.Type.CustomAttributes.Insert(0, new CodeAttributeDeclaration("System.ObsoleteAttribute"));
                                }

                                if (entity.Metadata.PrimaryNameAttribute != null)
                                {
                                    entity.Type.Members.Insert(2,
                                                               new CodeMemberField
                                    {
                                        Attributes     = System.CodeDom.MemberAttributes.Public | System.CodeDom.MemberAttributes.Const,
                                        Name           = "PrimaryNameAttribute",
                                        Type           = new CodeTypeReference(typeof(string)),
                                        InitExpression = new CodePrimitiveExpression(entity.Metadata.PrimaryNameAttribute)
                                    });
                                }

                                entity.Type.Members.Insert(2,
                                                           new CodeMemberField
                                {
                                    Attributes     = System.CodeDom.MemberAttributes.Public | System.CodeDom.MemberAttributes.Const,
                                    Name           = "PrimaryIdAttribute",
                                    Type           = new CodeTypeReference(typeof(string)),
                                    InitExpression = new CodePrimitiveExpression(entity.Metadata.PrimaryIdAttribute)
                                });

                                entity.Type.Members.Insert(2,
                                                           new CodeMemberField
                                {
                                    Attributes     = System.CodeDom.MemberAttributes.Public | System.CodeDom.MemberAttributes.Const,
                                    Name           = "EntitySchemaName",
                                    Type           = new CodeTypeReference(typeof(string)),
                                    InitExpression = new CodePrimitiveExpression(entity.Metadata.SchemaName)
                                });

                                entity.Type.Members.Insert(2,
                                                           new CodeMemberField
                                {
                                    Attributes     = System.CodeDom.MemberAttributes.Public | System.CodeDom.MemberAttributes.Const,
                                    Name           = "IsEntityActivityType",
                                    Type           = new CodeTypeReference(typeof(bool)),
                                    InitExpression = new CodePrimitiveExpression(entity.Metadata.IsActivity)
                                });
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 31
0
        void WriteCode(IOrganizationMetadata organizationMetadata)
        {
            MethodTracer.Enter();
            var tempFileName = Path.GetTempFileName();
            try
            {
                string outputDirectory;
                if (Parameters.OutputDirectory == null)
                {
                    outputDirectory = Environment.CurrentDirectory;
                }
                else
                {
                    outputDirectory = Parameters.OutputDirectory;
                }
                Directory.CreateDirectory(outputDirectory);
                ServiceProvider.CodeGenerationService.Write(organizationMetadata, "CS", tempFileName, Parameters.Namespace, ServiceProvider);

                using (var icc = CodeDomProvider.CreateProvider("CSharp"))
                {
                    var parameters = new CompilerParameters
                        {
                            OutputAssembly = Path.Combine(outputDirectory, Parameters.Namespace+ ".dll")
                        };
                    parameters.ReferencedAssemblies.Add(typeof (Entity).Assembly.Location);
                    parameters.ReferencedAssemblies.Add(typeof (Debug).Assembly.Location);
                    parameters.ReferencedAssemblies.Add(typeof (Enumerable).Assembly.Location);
                    parameters.ReferencedAssemblies.Add(typeof (DataContractAttribute).Assembly.Location);

                    var results = icc.CompileAssemblyFromFile(parameters, tempFileName);
                    if (results.Errors.HasErrors)
                    {
                        Console.WriteLine("Errors:");
                        foreach (var error in results.Errors)
                        {
                            Console.WriteLine(error);
                        }
                    }
                }
            }
            finally
            {
                File.Delete(tempFileName);
            }
            MethodTracer.Exit();
        }
Exemplo n.º 32
0
 public void Write(IOrganizationMetadata organizationMetadata, string language, string outputFile, string targetNamespace,
                   IServiceProvider services)
 {
     DefaultService.Write(organizationMetadata, language, outputFile, targetNamespace, services);
 }
        /// <summary>
        /// Remove the unnecessary classes that we generated for entities.
        /// </summary>
        public void CustomizeCodeDom(CodeCompileUnit codeUnit, IServiceProvider services)
        {
            var metadataProviderService    = (IMetadataProviderService)services.GetService(typeof(IMetadataProviderService));
            IOrganizationMetadata metadata = metadataProviderService.LoadMetadata();
            string baseTypes = GetParameter("/basetypes");

            foreach (CodeNamespace codeNamespace in codeUnit.Namespaces)
            {
                foreach (CodeTypeDeclaration codeTypeDeclaration in codeNamespace.Types)
                {
                    if (codeTypeDeclaration.IsClass)
                    {
                        codeTypeDeclaration.CustomAttributes.Clear();

                        if (!string.IsNullOrEmpty(baseTypes))
                        {
                            codeTypeDeclaration.BaseTypes.Clear();
                            codeTypeDeclaration.BaseTypes.Add(baseTypes);
                        }

                        foreach (EntityMetadata entityMetadata in metadata.Entities.Where(e => e.SchemaName == codeTypeDeclaration.Name))
                        {
                            for (var j = 0; j < codeTypeDeclaration.Members.Count;)
                            {
                                if (codeTypeDeclaration.Members[j].GetType() == typeof(System.CodeDom.CodeMemberProperty) && codeTypeDeclaration.Members[j].CustomAttributes.Count > 0 && codeTypeDeclaration.Members[j].CustomAttributes[0].AttributeType.BaseType == "Microsoft.Xrm.Sdk.AttributeLogicalNameAttribute")
                                {
                                    string attribute = ((System.CodeDom.CodePrimitiveExpression)codeTypeDeclaration.Members[j].CustomAttributes[0].Arguments[0].Value).Value.ToString();

                                    AttributeMetadata attributeMetadata = entityMetadata.Attributes.Where(a => a.LogicalName == attribute).FirstOrDefault();
                                    if (attributeMetadata != null)
                                    {
                                        IEnumerable <EnumItem> values = new List <EnumItem>();
                                        switch (attributeMetadata.AttributeType.Value)
                                        {
                                        case AttributeTypeCode.Boolean: values = ToUniqueValues(((BooleanAttributeMetadata)attributeMetadata).OptionSet); break;

                                        case AttributeTypeCode.Picklist: values = ToUniqueValues(((PicklistAttributeMetadata)attributeMetadata).OptionSet.Options); break;

                                        case AttributeTypeCode.State: values = ToUniqueValues(((StateAttributeMetadata)attributeMetadata).OptionSet.Options); break;

                                        case AttributeTypeCode.Status: values = ToUniqueValues(((StatusAttributeMetadata)attributeMetadata).OptionSet.Options); break;
                                        }

                                        switch (attributeMetadata.AttributeType.Value)
                                        {
                                        case AttributeTypeCode.Boolean:
                                            CodeTypeDeclaration booleanClass = new CodeTypeDeclaration(string.Format("{0}Values", attributeMetadata.LogicalName));
                                            booleanClass.IsClass    = true;
                                            booleanClass.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                                            booleanClass.CustomAttributes.Add(new CodeAttributeDeclaration {
                                                Name = "System.Xml.Serialization.XmlType", Arguments = { new CodeAttributeArgument {
                                                                                                             Name = "TypeName", Value = new CodePrimitiveExpression(string.Format("{0}.{1}.{2}Values", codeNamespace.Name, codeTypeDeclaration.Name, attributeMetadata.LogicalName))
                                                                                                         } }
                                            });

                                            foreach (EnumItem enumItem in values)
                                            {
                                                CodeMemberField codeMemberField = new CodeMemberField(typeof(bool), enumItem.Value);
                                                codeMemberField.Attributes     = MemberAttributes.Public | MemberAttributes.Const;
                                                codeMemberField.InitExpression = new CodePrimitiveExpression(enumItem.Key != 0);
                                                codeMemberField.CustomAttributes.Add(new CodeAttributeDeclaration {
                                                    Name = "System.ComponentModel.Description", Arguments = { new CodeAttributeArgument {
                                                                                                                  Value = new CodePrimitiveExpression(enumItem.Description)
                                                                                                              } }
                                                });
                                                booleanClass.Members.Add(codeMemberField);
                                            }

                                            codeTypeDeclaration.Members[j] = booleanClass;
                                            break;

                                        case AttributeTypeCode.Picklist:
                                        case AttributeTypeCode.State:
                                        case AttributeTypeCode.Status:
                                            CodeTypeDeclaration enumeration = new CodeTypeDeclaration
                                            {
                                                IsEnum = true,
                                                Name   = string.Format("{0}Values", attributeMetadata.LogicalName)
                                            };
                                            enumeration.CustomAttributes.Add(new CodeAttributeDeclaration {
                                                Name = "System.Xml.Serialization.XmlType", Arguments = { new CodeAttributeArgument {
                                                                                                             Name = "TypeName", Value = new CodePrimitiveExpression(string.Format("{0}.{1}.{2}Values", codeNamespace.Name, codeTypeDeclaration.Name, attributeMetadata.LogicalName))
                                                                                                         } }
                                            });

                                            foreach (EnumItem enumItem in values)
                                            {
                                                CodeMemberField codeMemberField = new CodeMemberField(string.Empty, enumItem.Value);
                                                codeMemberField.InitExpression = new CodePrimitiveExpression(enumItem.Key);
                                                codeMemberField.CustomAttributes.Add(new CodeAttributeDeclaration {
                                                    Name = "System.ComponentModel.Description", Arguments = { new CodeAttributeArgument {
                                                                                                                  Value = new CodePrimitiveExpression(enumItem.Description)
                                                                                                              } }
                                                });
                                                enumeration.Members.Add(codeMemberField);
                                            }

                                            codeTypeDeclaration.Members[j] = enumeration;
                                            break;
                                        }
                                        j++;
                                    }
                                    else
                                    {
                                        codeTypeDeclaration.Members.RemoveAt(j);
                                    }
                                }
                                else
                                {
                                    codeTypeDeclaration.Members.RemoveAt(j);
                                }
                            }
                        }
                    }
                }
            }

#if REMOVE_PROXY_TYPE_ASSEMBLY_ATTRIBUTE
            foreach (CodeAttributeDeclaration attribute in codeUnit.AssemblyCustomAttributes)
            {
                if (attribute.AttributeType.BaseType == "Microsoft.Xrm.Sdk.Client.ProxyTypesAssemblyAttribute")
                {
                    codeUnit.AssemblyCustomAttributes.Remove(attribute);
                    break;
                }
            }
#endif
        }