diff --git a/spkl/SparkleXrm.Tasks.Tests/EarlyBoundTypes.cs b/spkl/SparkleXrm.Tasks.Tests/EarlyBoundTypes.cs index beb2a527..d5108218 100644 --- a/spkl/SparkleXrm.Tasks.Tests/EarlyBoundTypes.cs +++ b/spkl/SparkleXrm.Tasks.Tests/EarlyBoundTypes.cs @@ -6,16 +6,89 @@ using System.Collections.Generic; using System.Configuration; using System.IO; -using System.Linq; -using System.Text; using System.Text.RegularExpressions; -using System.Threading.Tasks; namespace SparkleXrm.Tasks.Tests { [TestClass] public class EarlyBoundTypes { + [TestMethod] + [TestCategory("Integration Tests")] + public void TestEbgGenerateGlobalOptionsets() + { + // Arrange + Guid id = Guid.NewGuid(); + var tempFolder = Path.Combine(Path.GetTempPath(), id.ToString()); + Directory.CreateDirectory(tempFolder); + try + { + var config = new ConfigFile + { + earlyboundtypes = new List{ + new EarlyBoundTypeConfig{ + useEarlyBoundGeneratorApi = true, + generateOptionsetEnums = true, + entities ="socialprofile,socialactivity" + } + }, + filePath = tempFolder + + }; + Generate(tempFolder, config); + + // Check that there was only a single instance of the global optionsset 'socialprofile_community' + // public enum socialprofile_community + + var matches = CountMatches("public enum SocialProfile_Community", tempFolder); + Assert.AreEqual(1, matches, "Global optionset created once only"); + } + finally + { + Directory.Delete(tempFolder, true); + } + } + + [TestMethod] + [TestCategory("Integration Tests")] + public void TestEbgGenerateGlobalOptionsets_OneTypePerFile() + { + // Arrange + Guid id = Guid.NewGuid(); + var tempFolder = Path.Combine(Path.GetTempPath(), id.ToString()); + Directory.CreateDirectory(tempFolder); + try + { + var config = new ConfigFile + { + earlyboundtypes = new List{ + new EarlyBoundTypeConfig{ + generateOptionsetEnums = true, + useEarlyBoundGeneratorApi = true, + entities ="socialprofile,socialactivity", + oneTypePerFile = true + } + }, + filePath = tempFolder + + }; + Generate(tempFolder, config); + + + Assert.IsFalse(File.Exists(Path.Combine(tempFolder, "entities.cs"))); + + EnsureClassIsCreatedCorrectly(Path.Combine($"{tempFolder}\\Entities", "SocialProfile.cs"), "SocialProfile"); + EnsureClassIsCreatedCorrectly(Path.Combine($"{tempFolder}\\Entities", "SocialActivity.cs"), "SocialActivity"); + + EnsureOptionSetsIsCreatedCorrectly(Path.Combine($"{tempFolder}\\OptionSets", "socialprofile_community.cs"), "SocialProfile_Community"); + EnsureOptionSetsIsCreatedCorrectly(Path.Combine($"{tempFolder}\\OptionSets", "socialactivity_prioritycode.cs"), "SocialActivity_PriorityCode"); + } + finally + { + Directory.Delete(tempFolder, true); + } + } + [TestMethod] [TestCategory("Integration Tests")] public void TestGenerateGlobalOptionsets() @@ -222,7 +295,7 @@ public void TestNotGeneratingAnyOptionsets() Directory.Delete(tempFolder, true); } } - + [TestMethod] [TestCategory("Integration Tests")] public void TestNotGeneratingAnyOptionsets_OneTypePerFile() @@ -263,7 +336,7 @@ public void TestNotGeneratingAnyOptionsets_OneTypePerFile() Directory.Delete(tempFolder, true); } } - + private static void Generate(string tempFolder, ConfigFile config) { var connectionString = ConfigurationManager.ConnectionStrings["integration_testing"].ConnectionString; @@ -284,7 +357,6 @@ private static void Generate(string tempFolder, ConfigFile config) } } - private static void EnsureClassIsCreatedCorrectly(string classPath, string className) { var code = File.ReadAllText(classPath); @@ -298,5 +370,29 @@ private static void EnsureOptionSetsIsCreatedCorrectly(string optionSetsPath, st var matches = Regex.Matches(code, $"public enum {optionSetsName}"); Assert.AreEqual(1, matches.Count, $"Optionset {optionSetsName} created once only"); } + + private static int CountMatches(string matchString, string tempFolder) + { + var path = Path.Combine(tempFolder, "entities.cs"); + string code = File.ReadAllText(path); + var matches = Regex.Matches(code, matchString); + var count = matches.Count; + path = Path.Combine(tempFolder, "optionsets.cs"); + if (File.Exists(path)) + { + code = File.ReadAllText(path); + matches = Regex.Matches(code, matchString); + count += matches.Count; + } + + path = Path.Combine(tempFolder, "actions.cs"); + if (File.Exists(path)) + { + code = File.ReadAllText(path); + matches = Regex.Matches(code, matchString); + count += matches.Count; + } + return count; + } } } diff --git a/spkl/SparkleXrm.Tasks.Tests/SparkleXrm.Tasks.Tests.csproj b/spkl/SparkleXrm.Tasks.Tests/SparkleXrm.Tasks.Tests.csproj index ded8896e..4d0220ff 100644 --- a/spkl/SparkleXrm.Tasks.Tests/SparkleXrm.Tasks.Tests.csproj +++ b/spkl/SparkleXrm.Tasks.Tests/SparkleXrm.Tasks.Tests.csproj @@ -44,36 +44,51 @@ Plugins.snk + + ..\packages\DLaB.Xrm.EarlyBoundGenerator.Api.1.2020.5.5\lib\net462\DLaB.EarlyBoundGenerator.Api.dll + ..\packages\FakeItEasy.5.5.0\lib\net45\FakeItEasy.dll - ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.23\lib\net462\Microsoft.Crm.Sdk.Proxy.dll + ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.24\lib\net462\Microsoft.Crm.Sdk.Proxy.dll + True - - ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.5.2.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll + + ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.8\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll + True + + + ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.8\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll - ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.1.0.38\lib\net462\Microsoft.Rest.ClientRuntime.dll + ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.1.0.42\lib\net462\Microsoft.Rest.ClientRuntime.dll + True + False - ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.23\lib\net462\Microsoft.Xrm.Sdk.dll + ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.24\lib\net462\Microsoft.Xrm.Sdk.dll + True - ..\packages\Microsoft.CrmSdk.Deployment.9.0.2.23\lib\net462\Microsoft.Xrm.Sdk.Deployment.dll + ..\packages\Microsoft.CrmSdk.Deployment.9.0.2.24\lib\net462\Microsoft.Xrm.Sdk.Deployment.dll + True - ..\packages\Microsoft.CrmSdk.Workflow.9.0.2.23\lib\net462\Microsoft.Xrm.Sdk.Workflow.dll + ..\packages\Microsoft.CrmSdk.Workflow.9.0.2.24\lib\net462\Microsoft.Xrm.Sdk.Workflow.dll + True - ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.1.0.38\lib\net462\Microsoft.Xrm.Tooling.Connector.dll + ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.1.0.42\lib\net462\Microsoft.Xrm.Tooling.Connector.dll + True - - ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll + + ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + True @@ -188,6 +203,16 @@ Designer + + + + + + + + + + Designer @@ -209,6 +234,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spkl/SparkleXrm.Tasks.Tests/app.config b/spkl/SparkleXrm.Tasks.Tests/app.config index e3c44456..036ba1f5 100644 --- a/spkl/SparkleXrm.Tasks.Tests/app.config +++ b/spkl/SparkleXrm.Tasks.Tests/app.config @@ -3,7 +3,7 @@ - + @@ -73,7 +73,7 @@ - + diff --git a/spkl/SparkleXrm.Tasks.Tests/packages.config b/spkl/SparkleXrm.Tasks.Tests/packages.config index d4327beb..8a2df01d 100644 --- a/spkl/SparkleXrm.Tasks.Tests/packages.config +++ b/spkl/SparkleXrm.Tasks.Tests/packages.config @@ -1,13 +1,14 @@  + - - - - - + + + + + - + diff --git a/spkl/SparkleXrm.Tasks/Config/ConfigFile.cs b/spkl/SparkleXrm.Tasks/Config/ConfigFile.cs index 67f1e750..a62e19ef 100644 --- a/spkl/SparkleXrm.Tasks/Config/ConfigFile.cs +++ b/spkl/SparkleXrm.Tasks/Config/ConfigFile.cs @@ -58,7 +58,7 @@ public virtual SolutionPackageConfig[] GetSolutionConfig(string profile) public virtual EarlyBoundTypeConfig[] GetEarlyBoundConfig(string profile) { if (earlyboundtypes == null) - return new EarlyBoundTypeConfig[] { new EarlyBoundTypeConfig(){ + return new [] { new EarlyBoundTypeConfig{ filename ="Entities.cs", entities = "account,contact", classNamespace = "Xrm", @@ -66,20 +66,28 @@ public virtual EarlyBoundTypeConfig[] GetEarlyBoundConfig(string profile) generateStateEnums = true } }; + foreach (var type in earlyboundtypes) + { + if (string.IsNullOrEmpty(type.entities) && type.entityCollection?.Length > 0) + { + type.entities = string.Join(",", type.entityCollection); + } + + if (string.IsNullOrEmpty(type.actions) && type.actionCollection?.Length > 0) + { + type.actions = string.Join(",", type.actionCollection); + } + } + EarlyBoundTypeConfig[] config = null; if (profile == "default") { profile = null; } - if (profile != null) - { - config = earlyboundtypes.Where(c => c.profile != null && c.profile.Replace(" ", "").Split(',').Contains(profile)).ToArray(); - } - else - { - // Default profile or empty - config = earlyboundtypes.Where(c => c.profile == null || c.profile.Replace(" ", "").Split(',').Contains("default") || String.IsNullOrWhiteSpace(c.profile)).ToArray(); - } + + config = profile == null + ? earlyboundtypes.Where(c => c.profile == null || c.profile.Replace(" ", "").Split(',').Contains("default") || string.IsNullOrWhiteSpace(c.profile)).ToArray() + : earlyboundtypes.Where(c => c.profile != null && c.profile.Replace(" ", "").Split(',').Contains(profile)).ToArray(); return config; } diff --git a/spkl/SparkleXrm.Tasks/Config/EarlyBoundTypeConfig.cs b/spkl/SparkleXrm.Tasks/Config/EarlyBoundTypeConfig.cs index 7e0d6f33..eaa85dc1 100644 --- a/spkl/SparkleXrm.Tasks/Config/EarlyBoundTypeConfig.cs +++ b/spkl/SparkleXrm.Tasks/Config/EarlyBoundTypeConfig.cs @@ -1,24 +1,33 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SparkleXrm.Tasks.Config +namespace SparkleXrm.Tasks.Config { - public class EarlyBoundTypeConfig + public class EarlyBoundTypeConfig : DLaB.EarlyBoundGenerator.Settings.POCO.ExtensionConfig { + public bool useEarlyBoundGeneratorApi; + public string profile; public string entities; public string[] entityCollection; public string actions; public string[] actionCollection; public bool generateOptionsetEnums; - public bool generateGlobalOptionsets; - public bool generateStateEnums; public string filename; public string classNamespace; public string serviceContextName; public bool oneTypePerFile; + + #region Sprkl Generation Specific + + public bool generateGlobalOptionsets; + public bool generateStateEnums; + + #endregion Sprkl Generation Specific + + #region Early Bound Generator Specific + + public bool? generateActions; + public string actionFilename; + public string optionSetFilename; + + #endregion Early Bound Generator Specific } } \ No newline at end of file diff --git a/spkl/SparkleXrm.Tasks/SparkleXrm.Tasks.csproj b/spkl/SparkleXrm.Tasks/SparkleXrm.Tasks.csproj index 79bcf8a7..ad9ea418 100644 --- a/spkl/SparkleXrm.Tasks/SparkleXrm.Tasks.csproj +++ b/spkl/SparkleXrm.Tasks/SparkleXrm.Tasks.csproj @@ -37,6 +37,9 @@ SparkleXrm.snk + + ..\packages\DLaB.Xrm.EarlyBoundGenerator.Api.1.2020.5.5\lib\net462\DLaB.EarlyBoundGenerator.Api.dll + ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.23\lib\net462\Microsoft.Crm.Sdk.Proxy.dll True @@ -77,6 +80,7 @@ + @@ -174,6 +178,14 @@ + + + + + + + + @@ -204,6 +216,21 @@ + + + + + + + + + + + + + + + diff --git a/spkl/SparkleXrm.Tasks/Tasks/EarlyBoundClassGeneratorTask.cs b/spkl/SparkleXrm.Tasks/Tasks/EarlyBoundClassGeneratorTask.cs index 5f21dd4c..2b14a9d5 100644 --- a/spkl/SparkleXrm.Tasks/Tasks/EarlyBoundClassGeneratorTask.cs +++ b/spkl/SparkleXrm.Tasks/Tasks/EarlyBoundClassGeneratorTask.cs @@ -1,13 +1,11 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Client; using SparkleXrm.Tasks.Config; using System.IO; using System.Diagnostics; +using DLaB.EarlyBoundGenerator; +using DLaB.Log; using SparkleXrm.Tasks.CrmSvcUtil; namespace SparkleXrm.Tasks @@ -15,7 +13,6 @@ namespace SparkleXrm.Tasks public class EarlyBoundClassGeneratorTask : BaseTask { public string ConectionString {get;set;} - private string _folder; public EarlyBoundClassGeneratorTask(IOrganizationService service, ITrace trace) : base(service, trace) { } @@ -40,13 +37,147 @@ protected override void ExecuteInternal(string folder, OrganizationServiceContex } + public void CreateEarlyBoundTypes(OrganizationServiceContext ctx, ConfigFile config) { - _folder = config.filePath; + Logger.Instance.OnLog += DLaBOnLog; + var crmSvcUtilPath = GetCrmSvcUtilPath(); + GetSpkrlCrmSvcUtilPath(out var crmsvcutilPath, out var crmsvcutilFolder); + + var earlyBoundTypeConfigs = config.GetEarlyBoundConfig(Profile); + foreach (var earlyboundConfig in earlyBoundTypeConfigs) + { + if (earlyboundConfig.useEarlyBoundGeneratorApi) + { + ProcessEbgGeneration(config, earlyboundConfig, crmSvcUtilPath); + } + else + { + ProcessSprklGeneration(earlyboundConfig, crmsvcutilFolder, config.filePath, crmsvcutilPath); + } + } + } + + #region Early Bound Generator + + private void ProcessEbgGeneration(ConfigFile config, EarlyBoundTypeConfig earlyboundConfig, string crmSvcUtilPath) + { + var ebgConfig = DLaB.EarlyBoundGenerator.Settings.EarlyBoundGeneratorConfig.GetDefault(); + ebgConfig.ExtensionConfig.SetPopulatedValues(earlyboundConfig); + ebgConfig.ExtensionConfig.EntitiesWhitelist = ConvertCommasToPipes(earlyboundConfig.entities); + ebgConfig.ExtensionConfig.ActionsWhitelist = ConvertCommasToPipes(earlyboundConfig.actions); + ebgConfig.ExtensionConfig.GenerateEnumProperties = earlyboundConfig.generateOptionsetEnums; + ebgConfig.EntityOutPath = GetFile(config.filePath, earlyboundConfig.filename, "entities.cs", earlyboundConfig.oneTypePerFile); + ebgConfig.ActionOutPath = GetFile(config.filePath, earlyboundConfig.actionFilename, "actions.cs", earlyboundConfig.oneTypePerFile); + ebgConfig.OptionSetOutPath = GetFile(config.filePath, earlyboundConfig.optionSetFilename, "optionsets.cs", earlyboundConfig.oneTypePerFile); + ebgConfig.SupportsActions = earlyboundConfig.generateActions != false && !string.IsNullOrWhiteSpace(earlyboundConfig.actions); + ebgConfig.Namespace = earlyboundConfig.classNamespace ?? "Xrm"; + ebgConfig.ConnectionString = ConectionString; + ebgConfig.CrmSvcUtilRelativePath = crmSvcUtilPath; + ebgConfig.RootPath = Path.GetDirectoryName(crmSvcUtilPath); + ebgConfig.ServiceContextName = string.IsNullOrWhiteSpace(earlyboundConfig.serviceContextName) + ? ebgConfig.ServiceContextName + : earlyboundConfig.serviceContextName; + if (earlyboundConfig.oneTypePerFile) + { + ebgConfig.ExtensionConfig.CreateOneFilePerAction = true; + ebgConfig.ExtensionConfig.CreateOneFilePerEntity = true; + ebgConfig.ExtensionConfig.CreateOneFilePerOptionSet = true; + } + + + if (string.IsNullOrEmpty(ebgConfig.ConnectionString)) + { + throw new Exception("ConnectionString must be supplied for CrmSvcUtil"); + } + + var logic = new Logic(ebgConfig); + if (!earlyboundConfig.generateOptionsetEnums) + { + if (ebgConfig.SupportsActions) + { + logic.CreateActions(); + } + + logic.CreateEntities(); + } + else + { + new Logic(ebgConfig).ExecuteAll(); + } + } + + private void DLaBOnLog(LogMessageInfo info) + { + _trace.WriteLine(info.ModalMessage); + if (info.Detail != null && info.Detail != info.ModalMessage) + { + _trace.WriteLine(info.Detail); + } + } + + private string GetFile(string path, string configured, string fileTypeName, bool createOneFilePerType) + { + path = Path.Combine(path, string.IsNullOrWhiteSpace(configured) + ? fileTypeName + : configured); + if (createOneFilePerType && Path.GetExtension(path).ToLower() == ".cs") + { + path = Path.GetDirectoryName(path) + "\\" + Path.GetFileNameWithoutExtension(path) + "\\"; + } + return path; + } + + private string ConvertCommasToPipes(string value) + { + if (string.IsNullOrWhiteSpace(value)) + { + return null; + } + return value.Replace(',', '|'); + } + private string GetCrmSvcUtilPath() + { + // locate the CrmSvcUtil package folder + var targetFolder = ServiceLocator.DirectoryService.GetApplicationDirectory(); + + // If we are running in VS, then move up past bin/Debug + if (targetFolder.Contains(@"bin\Debug") || targetFolder.Contains(@"bin\Release")) + { + targetFolder += @"\.."; + } + + // move from spkl.v.v.v.\tools - back to packages folder + var path = Path.GetFullPath(targetFolder + @"\..\.."); + _trace.WriteLine("Target {0}", path); + var dLaBCrmSvcUtilExtPath = ServiceLocator.DirectoryService.SimpleSearch(path, "DLaB.CrmSvcUtilExtensions.dll"); + if (string.IsNullOrEmpty(dLaBCrmSvcUtilExtPath)) + { + throw new SparkleTaskException(SparkleTaskException.ExceptionTypes.UTILSNOTFOUND, + $"Cannot locate DLaB.CrmSvcUtilExtensions.dll anywhere within '{path}' - run Install-Package DLaB.EarlyBoundGenerator.Api"); + } + + var crmSvcUtilFolder = new FileInfo(dLaBCrmSvcUtilExtPath).DirectoryName; + var crmSvcUtilPath = ServiceLocator.DirectoryService.SimpleSearch(crmSvcUtilFolder, "CrmSvcUtil.exe"); + if (string.IsNullOrEmpty(crmSvcUtilPath)) + { + throw new SparkleTaskException(SparkleTaskException.ExceptionTypes.UTILSNOTFOUND, + $"Cannot locate CrmSvcUtil.exe at '{crmSvcUtilFolder}' - run Install-Package DLaB.EarlyBoundGenerator.Api"); + } + + return crmSvcUtilPath; + } + + #endregion // Early Bound Generator + + #region Sprkl Generatoor + + private void GetSpkrlCrmSvcUtilPath(out string crmsvcutilPath, out string crmsvcutilFolder) + { // locate the CrmSvcUtil package folder var targetfolder = ServiceLocator.DirectoryService.GetApplicationDirectory(); - + // If we are running in VS, then move up past bin/Debug if (targetfolder.Contains(@"bin\Debug") || targetfolder.Contains(@"bin\Release")) { @@ -54,9 +185,9 @@ public void CreateEarlyBoundTypes(OrganizationServiceContext ctx, ConfigFile con } // move from spkl.v.v.v.\tools - back to packages folder - var crmsvcutilPath = ServiceLocator.DirectoryService.SimpleSearch(targetfolder + @"\..\..", "crmsvcutil.exe"); + crmsvcutilPath = ServiceLocator.DirectoryService.SimpleSearch(targetfolder + @"\..\..", "crmsvcutil.exe"); _trace.WriteLine("Target {0}", targetfolder); - var crmsvcutilFolder = new FileInfo(crmsvcutilPath).DirectoryName; + crmsvcutilFolder = new FileInfo(crmsvcutilPath).DirectoryName; if (string.IsNullOrEmpty(crmsvcutilPath)) { throw new SparkleTaskException(SparkleTaskException.ExceptionTypes.UTILSNOTFOUND, @@ -65,12 +196,13 @@ public void CreateEarlyBoundTypes(OrganizationServiceContext ctx, ConfigFile con // Copy the filtering assembly var filteringAssemblyPathString = ServiceLocator.DirectoryService.SimpleSearch(targetfolder + @"\..\..", "spkl.CrmSvcUtilExtensions.dll"); - + if (string.IsNullOrEmpty(filteringAssemblyPathString)) { throw new SparkleTaskException(SparkleTaskException.ExceptionTypes.UTILSNOTFOUND, $"Cannot locate spkl.CrmSvcUtilExtensions.dll at '{crmsvcutilPath}' "); } + var filteringAssemblyPath = new FileInfo(filteringAssemblyPathString); var targetFilteringPath = Path.Combine(crmsvcutilFolder, "spkl.CrmSvcUtilExtensions.dll"); @@ -78,93 +210,81 @@ public void CreateEarlyBoundTypes(OrganizationServiceContext ctx, ConfigFile con { File.Copy(filteringAssemblyPath.FullName, targetFilteringPath, true); } + } - var earlyBoundTypeConfigs = config.GetEarlyBoundConfig(this.Profile); - foreach (var earlyboundconfig in earlyBoundTypeConfigs) - { - if(string.IsNullOrEmpty(earlyboundconfig.entities) && earlyboundconfig.entityCollection?.Length > 0) - { - earlyboundconfig.entities = string.Join(",", earlyboundconfig.entityCollection); - } - - if (string.IsNullOrEmpty(earlyboundconfig.actions) && earlyboundconfig.actionCollection?.Length > 0) - { - earlyboundconfig.actions = string.Join(",", earlyboundconfig.actionCollection); - } - - // Create config and copy to the CrmSvcUtil folder - var configXml = $@" + private void ProcessSprklGeneration(EarlyBoundTypeConfig earlyboundconfig, string crmsvcutilFolder, string folder, string crmsvcutilPath) + { + var configXml = $@" {earlyboundconfig.entities} {earlyboundconfig.actions} { - earlyboundconfig.generateOptionsetEnums.ToString().ToLower() - } + earlyboundconfig.generateOptionsetEnums.ToString().ToLower() + } {earlyboundconfig.generateStateEnums.ToString().ToLower()} {earlyboundconfig.generateGlobalOptionsets.ToString().ToLower()} "; - // Copy the filtering assembly to the CrmSvcUtil folder - File.WriteAllText(Path.Combine(crmsvcutilFolder, "spkl.crmsvcutil.config"), configXml); + // Copy the filtering assembly to the CrmSvcUtil folder + File.WriteAllText(Path.Combine(crmsvcutilFolder, "spkl.crmsvcutil.config"), configXml); - if (string.IsNullOrEmpty(this.ConectionString)) - throw new Exception("ConnectionString must be supplied for CrmSvcUtil"); + if (string.IsNullOrEmpty(ConectionString)) + throw new Exception("ConnectionString must be supplied for CrmSvcUtil"); - // Run CrmSvcUtil - var parameters = - $@"/connstr:""{this.ConectionString}"" /out:""{ - Path.Combine(this._folder, earlyboundconfig.filename) + // Run CrmSvcUtil + var parameters = + $@"/connstr:""{ConectionString}"" /out:""{ + Path.Combine(folder, earlyboundconfig.filename) }"" /namespace:""{earlyboundconfig.classNamespace}"" /serviceContextName:""{ earlyboundconfig.serviceContextName }"" /GenerateActions:""{ !String.IsNullOrEmpty(earlyboundconfig.actions) }"" /codewriterfilter:""spkl.CrmSvcUtilExtensions.FilteringService,spkl.CrmSvcUtilExtensions"" /codewritermessagefilter:""spkl.CrmSvcUtilExtensions.MessageFilteringService,spkl.CrmSvcUtilExtensions"" /codegenerationservice:""spkl.CrmSvcUtilExtensions.CodeGenerationService, spkl.CrmSvcUtilExtensions"" /metadataproviderqueryservice:""spkl.CrmSvcUtilExtensions.MetadataProviderQueryService,spkl.CrmSvcUtilExtensions"""; - var procStart = new ProcessStartInfo(crmsvcutilPath, parameters) - { - WorkingDirectory = crmsvcutilFolder, - RedirectStandardOutput = true, - RedirectStandardError = true, - CreateNoWindow = true, - UseShellExecute = false, - WindowStyle = ProcessWindowStyle.Hidden - }; - - _trace.WriteLine("Running {0} {1}", crmsvcutilPath, parameters); - var exitCode = 0; - Process proc = null; - try - { - proc = Process.Start(procStart); - proc.OutputDataReceived += Proc_OutputDataReceived; - proc.ErrorDataReceived += Proc_OutputDataReceived; - proc.BeginOutputReadLine(); - proc.BeginErrorReadLine(); - proc.WaitForExit(20 * 60 * 60 * 1000); - proc.CancelOutputRead(); - proc.CancelErrorRead(); - } - finally - { - exitCode = proc.ExitCode; - - proc.Close(); - } + var procStart = new ProcessStartInfo(crmsvcutilPath, parameters) + { + WorkingDirectory = crmsvcutilFolder, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = true, + UseShellExecute = false, + WindowStyle = ProcessWindowStyle.Hidden + }; - if (exitCode!=0) - { - throw new SparkleTaskException(SparkleTaskException.ExceptionTypes.CRMSVCUTIL_ERROR, $"CrmSvcUtil exited with error {exitCode}"); - } + _trace.WriteLine("Running {0} {1}", crmsvcutilPath, parameters); + var exitCode = 0; + Process proc = null; + try + { + proc = Process.Start(procStart); + proc.OutputDataReceived += Proc_OutputDataReceived; + proc.ErrorDataReceived += Proc_OutputDataReceived; + proc.BeginOutputReadLine(); + proc.BeginErrorReadLine(); + proc.WaitForExit(20 * 60 * 60 * 1000); + proc.CancelOutputRead(); + proc.CancelErrorRead(); + } + finally + { + exitCode = proc.ExitCode; - // Now that crmsvcutil has created the earlybound class file let's split it into separate files if this what the user wants - if (earlyboundconfig.oneTypePerFile) - { - _trace.WriteLine("oneTypePerFile=true : Splitting types into separate files..."); - SplitCrmSvcUtilOutputFileIntoOneFilePerType( - Path.Combine(_folder, earlyboundconfig.filename), - Path.Combine(_folder, Path.GetDirectoryName(earlyboundconfig.filename)), - earlyboundconfig.classNamespace); - } + proc.Close(); + } + + if (exitCode != 0) + { + throw new SparkleTaskException(SparkleTaskException.ExceptionTypes.CRMSVCUTIL_ERROR, $"CrmSvcUtil exited with error {exitCode}"); + } + + // Now that crmsvcutil has created the earlybound class file let's split it into separate files if this what the user wants + if (earlyboundconfig.oneTypePerFile) + { + _trace.WriteLine("oneTypePerFile=true : Splitting types into separate files..."); + SplitCrmSvcUtilOutputFileIntoOneFilePerType( + Path.Combine(folder, earlyboundconfig.filename), + Path.Combine(folder, Path.GetDirectoryName(earlyboundconfig.filename)), + earlyboundconfig.classNamespace); } } @@ -180,5 +300,7 @@ private void SplitCrmSvcUtilOutputFileIntoOneFilePerType(string earlyboundconfig var sourceCodeManipulator = new SourceCodeSplitter(_trace); sourceCodeManipulator.WriteToSeparateFiles(destinationDirectoryPath, sourceCode, typeNamespace); } + + #endregion } } diff --git a/spkl/SparkleXrm.Tasks/packages.config b/spkl/SparkleXrm.Tasks/packages.config index 86e70452..e26371dd 100644 --- a/spkl/SparkleXrm.Tasks/packages.config +++ b/spkl/SparkleXrm.Tasks/packages.config @@ -1,5 +1,6 @@  + diff --git a/spkl/spkl/packages.config b/spkl/spkl/packages.config index 1d8dc83f..374b0e98 100644 --- a/spkl/spkl/packages.config +++ b/spkl/spkl/packages.config @@ -1,6 +1,7 @@  + diff --git a/spkl/spkl/spkl.csproj b/spkl/spkl/spkl.csproj index d652530d..ea018cd5 100644 --- a/spkl/spkl/spkl.csproj +++ b/spkl/spkl/spkl.csproj @@ -38,6 +38,9 @@ ..\packages\CmdLine.1.0.7.509\lib\net40-Client\CmdLine.dll True + + ..\packages\DLaB.Xrm.EarlyBoundGenerator.Api.1.2020.5.5\lib\net462\DLaB.EarlyBoundGenerator.Api.dll + ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.23\lib\net462\Microsoft.Crm.Sdk.Proxy.dll True @@ -49,6 +52,7 @@ ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.1.0.38\lib\net462\Microsoft.Rest.ClientRuntime.dll True + ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.23\lib\net462\Microsoft.Xrm.Sdk.dll True @@ -79,6 +83,7 @@ ..\packages\System.Collections.Immutable.1.7.0\lib\netstandard2.0\System.Collections.Immutable.dll + @@ -163,6 +168,14 @@ + + + + + + + + Designer @@ -182,10 +195,6 @@ - - {ea2b393e-2c0e-4f80-a44c-712877a04870} - CrmSvcUtil.FilteringService - {439ffd12-81e6-41dd-8aed-35a526051d45} SparkleXrm.Tasks @@ -243,6 +252,21 @@ + + + + + + + + + + + + + + +