예제 #1
0
        public static void RegisterPluginsAndWorkflows <TPlugin>(string projectName)
        {
            var xrmFrameworkConfigSection = ConfigHelper.GetSection();

            var projectConfig = xrmFrameworkConfigSection.Projects.OfType <ProjectElement>()
                                .FirstOrDefault(p => p.Name == projectName);

            if (projectConfig == null)
            {
                var defaultColor = Console.ForegroundColor;
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine($"No reference to the project {projectName} has been found in the xrmFramework.config file.");
                Console.ForegroundColor = defaultColor;
                return;
            }

            var pluginSolutionUniqueName = projectConfig.TargetSolution;

            var connectionString = ConfigurationManager.ConnectionStrings[xrmFrameworkConfigSection.SelectedConnection].ConnectionString;

            Console.WriteLine($"You are about to deploy on {connectionString} organization. If ok press any key.");
            Console.ReadKey();
            Console.WriteLine("Connecting to CRM...");

            var service = new CrmServiceClient(connectionString);

            service.OrganizationServiceProxy?.EnableProxyTypes();

            InitMetadata(service, pluginSolutionUniqueName);

            var pluginAssembly = typeof(TPlugin).Assembly;

            var pluginType    = pluginAssembly.GetType("XrmFramework.Plugin");
            var customApiType = pluginAssembly.GetType("XrmFramework.CustomApi");
            var workflowType  = pluginAssembly.GetType("XrmFramework.Workflow.CustomWorkflowActivity");

            var pluginList = new List <Plugin>();

            var pluginTypes = pluginAssembly.GetTypes().Where(t => pluginType.IsAssignableFrom(t) && !customApiType.IsAssignableFrom(t) && t.IsPublic && !t.IsAbstract).ToList();

            var workflowTypes = pluginAssembly.GetTypes().Where(t => workflowType.IsAssignableFrom(t) && !t.IsAbstract && t.IsPublic).ToList();

            var customApiTypes = pluginAssembly.GetTypes().Where(t => customApiType.IsAssignableFrom(t) && t.IsPublic && !t.IsAbstract).ToList();

            foreach (var type in pluginTypes)
            {
                dynamic pluginTemp;
                if (type.GetConstructor(new[] { typeof(string), typeof(string) }) != null)
                {
                    pluginTemp = Activator.CreateInstance(type, new object[] { null, null });
                }
                else
                {
                    pluginTemp = Activator.CreateInstance(type, new object[] { });
                }

                var plugin = Plugin.FromXrmFrameworkPlugin(pluginTemp, false);

                pluginList.Add(plugin);
            }

            foreach (var type in workflowTypes)
            {
                dynamic pluginTemp = Activator.CreateInstance(type, new object[] { });

                var plugin = Plugin.FromXrmFrameworkPlugin(pluginTemp, true);

                pluginList.Add(plugin);
            }

            var customApis = new List <CustomApi>();

            foreach (var type in customApiTypes)
            {
                dynamic customApiTemp;
                if (type.GetConstructor(new[] { typeof(string), typeof(string) }) != null)
                {
                    customApiTemp = Activator.CreateInstance(type, new object[] { null, null });
                }
                else
                {
                    customApiTemp = Activator.CreateInstance(type, new object[] { });
                }

                var customApi = CustomApi.FromXrmFrameworkCustomApi(customApiTemp, _publisher.CustomizationPrefix);

                customApis.Add(customApi);
            }


            var assembly = GetAssemblyByName(service, pluginAssembly.GetName().Name);

            var profilerAssembly = GetProfilerAssembly(service);

            var registeredPluginTypes = new List <PluginType>();
            var registeredCustomApis  = new List <CustomApi>();
            var registeredCustomApiRequestParameters  = new List <CustomApiRequestParameter>();
            var registeredCustomApiResponseProperties = new List <CustomApiResponseProperty>();
            var profiledSteps = new List <SdkMessageProcessingStep>();
            ICollection <SdkMessageProcessingStep> registeredSteps = Enumerable.Empty <SdkMessageProcessingStep>().ToList();

            var assemblyPath = pluginAssembly.Location;

            if (assembly == null)
            {
                Console.WriteLine("Registering assembly");

                assembly = GetAssemblyToRegister(pluginAssembly, assemblyPath);

                assembly.Id = service.Create(assembly);
            }
            else
            {
                Console.WriteLine("Updating plugin assembly");

                var updatedAssembly = new Entity("pluginassembly")
                {
                    Id          = assembly.Id,
                    ["content"] = Convert.ToBase64String(File.ReadAllBytes(assemblyPath))
                };

                registeredPluginTypes = GetRegisteredPluginTypes(service, assembly.Id).ToList();
                registeredCustomApis  = GetRegisteredCustomApis(service).ToList();
                registeredCustomApiRequestParameters  = GetRegisteredCustomApiRequestParameters(service).ToList();
                registeredCustomApiResponseProperties = GetRegisteredCustomApiResponseProperties(service).ToList();

                registeredSteps = GetRegisteredSteps(service, assembly.Id);

                if (profilerAssembly != null)
                {
                    profiledSteps = GetRegisteredSteps(service, profilerAssembly.Id).ToList();
                }

                foreach (var registeredType in registeredPluginTypes)
                {
                    if (pluginList.All(p => p.FullName != registeredType.Name) && pluginList.Where(p => p.IsWorkflow).All(c => c.FullName != registeredType.TypeName) && customApis.All(c => c.FullName != registeredType.TypeName))
                    {
                        var registeredStepsForPluginType = registeredSteps.Where(s => s.EventHandler.Id == registeredType.Id).ToList();
                        foreach (var step in registeredStepsForPluginType)
                        {
                            service.Delete(SdkMessageProcessingStep.EntityLogicalName, step.Id);
                            registeredSteps.Remove(step);
                        }

                        foreach (var customApi in registeredCustomApis.Where(c => c.PluginTypeId?.Id == registeredType.Id))
                        {
                            service.Delete(customApi.LogicalName, customApi.Id);
                        }

                        service.Delete(PluginType.EntityLogicalName, registeredType.Id);
                    }
                }

                service.Update(updatedAssembly);
            }

            AddSolutionComponentToSolution(service, pluginSolutionUniqueName, assembly.ToEntityReference());

            var registeredImages = GetRegisteredImages(service, assembly.Id);

            Console.WriteLine();
            Console.WriteLine(@"Registering Plugins");

            foreach (var plugin in pluginList.Where(p => !p.IsWorkflow))
            {
                Console.WriteLine($@"  - {plugin.FullName}");

                var registeredPluginType = registeredPluginTypes.FirstOrDefault(p => p.Name == plugin.FullName);

                if (registeredPluginType == null)
                {
                    registeredPluginType    = GetPluginTypeToRegister(assembly.Id, plugin.FullName);
                    registeredPluginType.Id = service.Create(registeredPluginType);
                }

                var registeredStepsForPluginType = registeredSteps.Where(s => s.EventHandler.Id == registeredPluginType.Id).ToList();

                var comparer = new SdkMessageStepComparer();

                foreach (var convertedStep in plugin.Steps)
                {
                    var stepToRegister = GetStepToRegister(registeredPluginType.Id, convertedStep);

                    var registeredStep = registeredStepsForPluginType.FirstOrDefault(s => comparer.Equals(s, stepToRegister));

                    if (registeredStep == null)
                    {
                        stepToRegister.Id = service.Create(stepToRegister);
                    }
                    else
                    {
                        registeredSteps.Remove(registeredStep);
                        stepToRegister.Id = registeredStep.Id;
                        if (comparer.NeedsUpdate(stepToRegister, registeredStep))
                        {
                            var profiledStep = profiledSteps.FirstOrDefault(p => p.Name.StartsWith(registeredStep.Name));

                            if (profiledStep != null)
                            {
                                service.Delete(profiledStep.LogicalName, profiledStep.Id);

                                service.Execute(new SetStateRequest
                                {
                                    EntityMoniker = registeredStep.ToEntityReference(),
                                    State         = new OptionSetValue((int)SdkMessageProcessingStepState.Enabled),
                                    Status        = new OptionSetValue(-1)
                                });
                            }

                            service.Update(stepToRegister);
                        }
                    }

                    AddSolutionComponentToSolution(service, pluginSolutionUniqueName, stepToRegister.ToEntityReference());

                    if (convertedStep.Message != Messages.Associate.ToString() && convertedStep.Message != Messages.Lose.ToString() && convertedStep.Message != Messages.Win.ToString())
                    {
                        var registeredPostImage = registeredImages.FirstOrDefault(i => i.Name == "PostImage" && i.SdkMessageProcessingStepId.Id == stepToRegister.Id);

                        if (convertedStep.PostImageUsed && convertedStep.Message != Messages.Delete.ToString())
                        {
                            if (registeredPostImage == null)
                            {
                                registeredPostImage    = GetImageToRegister(service, stepToRegister.Id, convertedStep, false);
                                registeredPostImage.Id = service.Create(registeredPostImage);
                            }
                            else if (registeredPostImage.Attributes1 != convertedStep.JoinedPostImageAttributes)
                            {
                                registeredPostImage.Attributes1 = convertedStep.JoinedPostImageAttributes;
                                service.Update(registeredPostImage);
                            }
                        }
                        else if (registeredPostImage != null)
                        {
                            service.Delete(registeredPostImage.LogicalName, registeredPostImage.Id);
                        }

                        var registeredPreImage = registeredImages.FirstOrDefault(i => i.Name == "PreImage" && i.SdkMessageProcessingStepId.Id == stepToRegister.Id);

                        if (convertedStep.PreImageUsed)
                        {
                            if (registeredPreImage == null)
                            {
                                registeredPreImage    = GetImageToRegister(service, stepToRegister.Id, convertedStep, true);
                                registeredPreImage.Id = service.Create(registeredPreImage);
                            }
                            else if (registeredPreImage.Attributes1 != convertedStep.JoinedPreImageAttributes)
                            {
                                registeredPreImage.Attributes1 = convertedStep.JoinedPreImageAttributes;
                                service.Update(registeredPreImage);
                            }
                        }
                        else if (registeredPreImage != null)
                        {
                            service.Delete(registeredPreImage.LogicalName, registeredPreImage.Id);
                        }
                    }
                }
            }

            Console.WriteLine();
            Console.WriteLine(@"Registering Custom Workflow activities");

            foreach (var customWf in pluginList.Where(p => p.IsWorkflow))
            {
                var registeredPluginType = registeredPluginTypes.FirstOrDefault(p => p.TypeName == customWf.FullName);

                Console.WriteLine($@"  - {customWf.FullName}");

                if (registeredPluginType == null)
                {
                    registeredPluginType    = GetCustomWorkflowTypeToRegister(assembly.Id, customWf.FullName, customWf.DisplayName);
                    registeredPluginType.Id = service.Create(registeredPluginType);
                }
                if (registeredPluginType.Name != customWf.DisplayName)
                {
                    registeredPluginType.Name = customWf.DisplayName;
                    service.Update(registeredPluginType);
                }
            }

            Console.WriteLine();
            Console.WriteLine(@"Registering Custom Apis");

            foreach (var customApi in customApis)
            {
                Console.WriteLine($@"  - {customApi.FullName}");

                var registeredPluginType = registeredPluginTypes.FirstOrDefault(p => p.Name == customApi.FullName);

                if (registeredPluginType == null)
                {
                    registeredPluginType    = GetPluginTypeToRegister(assembly.Id, customApi.FullName);
                    registeredPluginType.Id = service.Create(registeredPluginType);
                }

                customApi.PluginTypeId = new EntityReference(PluginType.EntityLogicalName, registeredPluginType.Id);

                var existingCustomApi = registeredCustomApis.FirstOrDefault(c => c.UniqueName == customApi.UniqueName);

                if (existingCustomApi == null)
                {
                    existingCustomApi    = customApi;
                    existingCustomApi.Id = service.Create(customApi);
                }
                else
                {
                    customApi.Id = existingCustomApi.Id;
                    service.Update(customApi);
                }

                foreach (var customApiRequestParameter in customApi.InArguments)
                {
                    var existingRequestParameter = registeredCustomApiRequestParameters.FirstOrDefault(p => p.UniqueName == customApiRequestParameter.UniqueName && p.CustomApiId.Id == existingCustomApi.Id);

                    customApiRequestParameter.CustomApiId = new EntityReference(CustomApi.EntityLogicalName, existingCustomApi.Id);

                    if (existingRequestParameter == null)
                    {
                        service.Create(customApiRequestParameter);
                    }
                    else
                    {
                        customApiRequestParameter.Id = existingRequestParameter.Id;
                        service.Update(customApiRequestParameter);
                    }
                }

                foreach (var customApiResponseProperty in customApi.OutArguments)
                {
                    var existingResponseProperty = registeredCustomApiResponseProperties.FirstOrDefault(p => p.UniqueName == customApiResponseProperty.UniqueName && p.CustomApiId.Id == existingCustomApi.Id);

                    customApiResponseProperty.CustomApiId = new EntityReference(CustomApi.EntityLogicalName, existingCustomApi.Id);

                    if (existingResponseProperty == null)
                    {
                        service.Create(customApiResponseProperty);
                    }
                    else
                    {
                        customApiResponseProperty.Id = existingResponseProperty.Id;
                        service.Update(customApiResponseProperty);
                    }
                }
            }

            Console.WriteLine();

            foreach (var step in registeredSteps)
            {
                service.Delete(SdkMessageProcessingStep.EntityLogicalName, step.Id);
            }
        }