diff --git a/.paket/Paket.Restore.targets b/.paket/Paket.Restore.targets index e7c1bc0c..52f41c60 100644 --- a/.paket/Paket.Restore.targets +++ b/.paket/Paket.Restore.targets @@ -11,23 +11,49 @@ $(MSBuildThisFileDirectory)..\ $(PaketRootPath)paket-files\paket.restore.cached $(PaketRootPath)paket.lock + classic + proj + assembly + native /Library/Frameworks/Mono.framework/Commands/mono mono - - $(PaketRootPath)paket.exe - $(PaketToolsPath)paket.exe - "$(PaketExePath)" - $(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)" - + + $(PaketRootPath)paket.bootstrapper.exe + $(PaketToolsPath)paket.bootstrapper.exe + $([System.IO.Path]::GetDirectoryName("$(PaketBootStrapperExePath)"))\ + + + + + $(PaketRootPath)paket.exe + $(PaketToolsPath)paket.exe + $(PaketToolsPath)paket.exe + $(_PaketBootStrapperExeDir)paket.exe + paket.exe + + + $(PaketRootPath)paket + $(PaketToolsPath)paket + $(PaketToolsPath)paket + + + $(PaketRootPath)paket.exe + $(PaketToolsPath)paket.exe + + + $(PaketBootStrapperExeDir)paket.exe + + + paket + + <_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)")) - dotnet "$(PaketExePath)" + dotnet "$(PaketExePath)" + $(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)" + "$(PaketExePath)" - - "$(PaketExePath)" - $(PaketRootPath)paket.bootstrapper.exe - $(PaketToolsPath)paket.bootstrapper.exe "$(PaketBootStrapperExePath)" $(MonoPath) --runtime=v4.0.30319 "$(PaketBootStrapperExePath)" @@ -36,30 +62,40 @@ true true + + + True - + + + + + true - $(NoWarn);NU1603 + $(NoWarn);NU1603;NU1604;NU1605;NU1608 - /usr/bin/shasum $(PaketRestoreCacheFile) | /usr/bin/awk '{ print $1 }' - /usr/bin/shasum $(PaketLockFilePath) | /usr/bin/awk '{ print $1 }' + /usr/bin/shasum "$(PaketRestoreCacheFile)" | /usr/bin/awk '{ print $1 }' + /usr/bin/shasum "$(PaketLockFilePath)" | /usr/bin/awk '{ print $1 }' - + - + + + + $([System.IO.File]::ReadAllText('$(PaketRestoreCacheFile)')) @@ -69,11 +105,26 @@ true + + + true + + - + + + + + + + + $(MSBuildProjectDirectory)\obj\$(MSBuildProjectFile).paket.references.cached @@ -82,7 +133,9 @@ $(MSBuildProjectDirectory)\$(MSBuildProjectName).paket.references $(MSBuildProjectDirectory)\paket.references - $(MSBuildProjectDirectory)\obj\$(MSBuildProjectFile).$(TargetFramework).paket.resolved + + false + true true references-file-or-cache-not-found @@ -101,32 +154,43 @@ - + true - target-framework '$(TargetFramework)' + target-framework '$(TargetFramework)' or '$(TargetFrameworks)' files @(PaketResolvedFilePaths) - + + - + + false + true + + - + - + + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',').Length) $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0]) $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1]) $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[4]) + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5]) %(PaketReferencesFileLinesInfo.PackageVersion) - All + All + runtime + runtime + true + true @@ -158,19 +222,27 @@ false + $(MSBuildVersion) + 15.8.0 <_NuspecFilesNewLocation Include="$(BaseIntermediateOutputPath)$(Configuration)\*.nuspec"/> + + $(MSBuildProjectDirectory)/$(MSBuildProjectFile) true - false - true + false + true + false + true + false + true $(BaseIntermediateOutputPath)$(Configuration) $(BaseIntermediateOutputPath) @@ -183,11 +255,54 @@ - - + - + + - --> - + True @@ -115,7 +115,7 @@ - + True @@ -141,7 +141,7 @@ - + ..\..\..\packages\crm2011\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/src/MetadataGen/MetadataGenerator13/MetadataGenerator13.csproj b/src/MetadataGen/MetadataGenerator13/MetadataGenerator13.csproj index 7ac8c224..7cdb8a24 100644 --- a/src/MetadataGen/MetadataGenerator13/MetadataGenerator13.csproj +++ b/src/MetadataGen/MetadataGenerator13/MetadataGenerator13.csproj @@ -115,7 +115,7 @@ - + True @@ -185,7 +185,7 @@ - + True @@ -214,7 +214,7 @@ - + ..\..\..\packages\crm2013\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/src/MetadataGen/MetadataGenerator15/MetadataGenerator15.csproj b/src/MetadataGen/MetadataGenerator15/MetadataGenerator15.csproj index 41d68f2b..e0c38905 100644 --- a/src/MetadataGen/MetadataGenerator15/MetadataGenerator15.csproj +++ b/src/MetadataGen/MetadataGenerator15/MetadataGenerator15.csproj @@ -62,7 +62,7 @@ --> - + True @@ -102,7 +102,7 @@ - + True @@ -131,7 +131,7 @@ - + ..\..\..\packages\crm2015\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/src/MetadataGen/MetadataGenerator16/MetadataGenerator16.csproj b/src/MetadataGen/MetadataGenerator16/MetadataGenerator16.csproj index 128d562f..bcd9c1f8 100644 --- a/src/MetadataGen/MetadataGenerator16/MetadataGenerator16.csproj +++ b/src/MetadataGen/MetadataGenerator16/MetadataGenerator16.csproj @@ -65,7 +65,7 @@ --> - + True @@ -105,7 +105,7 @@ - + True @@ -134,7 +134,7 @@ - + ..\..\..\packages\crm2016\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/src/MetadataGen/MetadataGenerator365/App.config b/src/MetadataGen/MetadataGenerator365/App.config index 495ee6c9..7dbcf7f9 100644 --- a/src/MetadataGen/MetadataGenerator365/App.config +++ b/src/MetadataGen/MetadataGenerator365/App.config @@ -1,4 +1,21 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/MetadataGen/MetadataGenerator365/MetadataGenerator365.csproj b/src/MetadataGen/MetadataGenerator365/MetadataGenerator365.csproj index d75c2458..b78ee26b 100644 --- a/src/MetadataGen/MetadataGenerator365/MetadataGenerator365.csproj +++ b/src/MetadataGen/MetadataGenerator365/MetadataGenerator365.csproj @@ -65,7 +65,7 @@ --> - + True @@ -105,7 +105,7 @@ - + True @@ -134,7 +134,7 @@ - + ..\..\..\packages\crm365\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/src/MetadataShared/DataHelper.cs b/src/MetadataShared/DataHelper.cs index 9ec403d0..271692ad 100644 --- a/src/MetadataShared/DataHelper.cs +++ b/src/MetadataShared/DataHelper.cs @@ -27,9 +27,11 @@ internal class DataHelper { private HashSet EntityLogicalNames; private string[] SolutionNames; - public DataHelper(IOrganizationService service, string entitiesString, string solutionsString, bool fetchFromAssemblies) { + public DataHelper(IOrganizationService service, string entitiesString, string solutionsString, + bool fetchFromAssemblies) + { this.service = service; - this.SolutionNames = solutionsString.Split(',').Select(x => x.Trim()).ToArray(); + this.SolutionNames = solutionsString.Split(new string[] { ","},StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToArray(); this.EntityLogicalNames = new HashSet(); // Add entites from assemblies @@ -48,6 +50,27 @@ public DataHelper(IOrganizationService service, string entitiesString, string so this.EntityLogicalNames.Add(logicalName.Trim()); } } + + if (SolutionNames.Length == 0 && string.IsNullOrEmpty(entitiesString)) + { + //load all entities from crm + RetrieveAllEntitiesRequest request = new RetrieveAllEntitiesRequest() + { + EntityFilters = EntityFilters.Entity, + RetrieveAsIfPublished = true + }; + + // Retrieve the MetaData. + RetrieveAllEntitiesResponse response = (RetrieveAllEntitiesResponse)service.Execute(request); + foreach (var emd in response.EntityMetadata) + { + if (!EntityLogicalNames.Contains(emd.LogicalName)) + { + EntityLogicalNames.Add(emd.LogicalName); + } + } + } + } public MetadataSkeleton GetMetadata(string path) { @@ -61,6 +84,8 @@ public MetadataSkeleton GetMetadata(string path) { Console.WriteLine("Getting plugins"); skeleton.Plugins = GetPlugins(this.SolutionNames); + Console.WriteLine(skeleton.Plugins.Count + " Plugin steps found"); + Console.WriteLine("Getting organization"); skeleton.BaseOrganization = GetBaseOrganization(); @@ -111,12 +136,14 @@ private IEnumerable GetEntityMetadata(string[] solutions, string } private List GetPlugins(string[] solutions) { - if (solutions == null || solutions.Length == 0) { - return new List(); - } + //if (solutions == null || solutions.Length == 0) { + // return new List(); + //} + + solutions = solutions.Where(s => !string.IsNullOrEmpty(s)).ToArray(); var pluginQuery = new QueryExpression("sdkmessageprocessingstep") { - ColumnSet = new ColumnSet("eventhandler", "stage", "mode", "rank", "sdkmessageid", "filteringattributes", "name"), + ColumnSet = new ColumnSet("eventhandler", "stage", "mode", "rank", "sdkmessageid", "filteringattributes", "name","configuration"), Criteria = new FilterExpression() }; pluginQuery.Criteria.AddCondition("statecode", ConditionOperator.Equal, 0); @@ -128,57 +155,54 @@ private List GetPlugins(string[] solutions) { }; pluginQuery.LinkEntities.Add(sdkMessageFilterQuery); - var solutionComponentQuery = new LinkEntity("sdkmessageprocessingstep", "solutioncomponent", "sdkmessageprocessingstepid", "objectid", JoinOperator.Inner) { - Columns = new ColumnSet(), - LinkCriteria = new FilterExpression() - }; - pluginQuery.LinkEntities.Add(solutionComponentQuery); - - var solutionQuery = new LinkEntity("solutioncomponent", "solution", "solutionid", "solutionid", JoinOperator.Inner) { - Columns = new ColumnSet(), - LinkCriteria = new FilterExpression() - }; - solutionQuery.LinkCriteria.AddCondition("uniquename", ConditionOperator.In, solutions); - solutionComponentQuery.LinkEntities.Add(solutionQuery); + EntityCollection images = new EntityCollection(); + if (solutions.Length > 0) + { + var solutionComponentQuery = new LinkEntity("sdkmessageprocessingstep", "solutioncomponent", "sdkmessageprocessingstepid", "objectid", JoinOperator.Inner) + { + Columns = new ColumnSet(), + LinkCriteria = new FilterExpression() + }; + pluginQuery.LinkEntities.Add(solutionComponentQuery); + var solutionQuery = new LinkEntity("solutioncomponent", "solution", "solutionid", "solutionid", JoinOperator.Inner) + { + Columns = new ColumnSet(), + LinkCriteria = new FilterExpression() + }; + solutionQuery.LinkCriteria.AddCondition("uniquename", ConditionOperator.In, solutions); + solutionComponentQuery.LinkEntities.Add(solutionQuery); + } var imagesQuery = new QueryExpression { EntityName = "sdkmessageprocessingstepimage", - ColumnSet = new ColumnSet("attributes", "entityalias", "name", "imagetype", "sdkmessageprocessingstepid"), - LinkEntities = - { - new LinkEntity("sdkmessageprocessingstepimage", "sdkmessageprocessingstep", "sdkmessageprocessingstepid", "sdkmessageprocessingstepid", JoinOperator.Inner) - { - LinkEntities = - { - new LinkEntity("sdkmessageprocessingstep", "solutioncomponent", "sdkmessageprocessingstepid", "objectid", JoinOperator.Inner) - { - LinkEntities = - { - new LinkEntity("solutioncomponent", "solution", "solutionid", "solutionid", JoinOperator.Inner) - { - LinkCriteria = - { - Conditions = - { - new ConditionExpression("uniquename", ConditionOperator.In, new [] { "PwCOrlenFlotaRelease001"}) - } - } - } - } - } - } - } - } + ColumnSet = new ColumnSet("attributes", "entityalias", "name", "imagetype", "sdkmessageprocessingstepid") }; + var msgprocstepimage = new LinkEntity("sdkmessageprocessingstepimage", "sdkmessageprocessingstep", "sdkmessageprocessingstepid", "sdkmessageprocessingstepid", JoinOperator.Inner); - var images = service.RetrieveMultiple(imagesQuery); - var plugins = new List(); + if (solutions.Length > 0) + { + var msgprocstep = new LinkEntity("sdkmessageprocessingstep", "solutioncomponent", "sdkmessageprocessingstepid", "objectid", JoinOperator.Inner); + var solsLinkEntity = new LinkEntity("solutioncomponent", "solution", "solutionid", "solutionid", JoinOperator.Inner); + solsLinkEntity.LinkCriteria.Conditions.Add(new ConditionExpression("uniquename", ConditionOperator.In, new[] { solutions })); + msgprocstep.LinkEntities.Add(solsLinkEntity); + msgprocstepimage.LinkEntities.Add(msgprocstep); + } - foreach (var plugin in service.RetrieveMultiple(pluginQuery).Entities) { - var metaPlugin = new MetaPlugin() { + + imagesQuery.LinkEntities.Add(msgprocstepimage); + + images = service.RetrieveMultiple(imagesQuery); + + + var plugins = new List(); + var allplugins = RetrieveLarge(service, pluginQuery).Entities; + foreach (var plugin in allplugins) + { + var metaPlugin = new MetaPlugin() + { Name = plugin.GetAttributeValue("name"), Rank = plugin.GetAttributeValue("rank"), FilteredAttributes = plugin.GetAttributeValue("filteringattributes"), @@ -186,6 +210,7 @@ private List GetPlugins(string[] solutions) { Stage = plugin.GetAttributeValue("stage").Value, MessageName = plugin.GetAttributeValue("sdkmessageid").Name, AssemblyName = plugin.GetAttributeValue("eventhandler").Name, + UnsecureConfiguration = plugin.GetAttributeValue("configuration"), PrimaryEntity = plugin.GetAttributeValue("sdkmessagefilter.primaryobjecttypecode").Value as string, Images = images.Entities .Where(x => x.GetAttributeValue("sdkmessageprocessingstepid").Id == plugin.Id) @@ -204,6 +229,44 @@ private List GetPlugins(string[] solutions) { return plugins; } + public EntityCollection RetrieveLarge(IOrganizationService organizationService, QueryBase query) + { + var entityCollection = new EntityCollection(); + RetrieveMultipleResponse multipleResponse = new RetrieveMultipleResponse(); + int pageNumber = 1; + do + { + if (query is QueryExpression) + { + (query as QueryExpression).PageInfo.Count = 5000; + (query as QueryExpression).PageInfo.PagingCookie = (pageNumber == 1) + ? null + : multipleResponse.EntityCollection.PagingCookie; + (query as QueryExpression).PageInfo.PageNumber = pageNumber++; + } + else if (query is QueryByAttribute) + { + (query as QueryByAttribute).PageInfo.Count = 5000; + (query as QueryByAttribute).PageInfo.PagingCookie = (pageNumber == 1) + ? null + : multipleResponse.EntityCollection.PagingCookie; + (query as QueryByAttribute).PageInfo.PageNumber = pageNumber++; + + } + else + { + return null; + } + RetrieveMultipleRequest multipleRequest = new RetrieveMultipleRequest { Query = query }; + multipleResponse = (RetrieveMultipleResponse)organizationService.Execute(multipleRequest); + + entityCollection.Entities.AddRange(multipleResponse.EntityCollection.Entities); + } while (multipleResponse.EntityCollection.MoreRecords); + + return entityCollection; + + } + private List GetCurrencies() { var query = new QueryExpression("transactioncurrency") { ColumnSet = new ColumnSet(true) diff --git a/src/MetadataShared/Program.cs b/src/MetadataShared/Program.cs index 37f39356..ef4aba9b 100644 --- a/src/MetadataShared/Program.cs +++ b/src/MetadataShared/Program.cs @@ -32,6 +32,8 @@ private static Assembly ResolveXrmAssemblies(object sender, ResolveEventArgs arg static void Main(string[] args) { + //Console.WriteLine("attach debugger now! Press Enter when done..."); + //Console.ReadLine(); ParsedArgs = new ArgumentParser(Arguments.ArgList, args); AppDomain.CurrentDomain.AssemblyResolve += ResolveXrmAssemblies; GenerateMetadata(); diff --git a/src/MetadataSkeleton/MetadataSkeleton.cs b/src/MetadataSkeleton/MetadataSkeleton.cs index f774518d..52a23844 100644 --- a/src/MetadataSkeleton/MetadataSkeleton.cs +++ b/src/MetadataSkeleton/MetadataSkeleton.cs @@ -26,6 +26,7 @@ public class MetaPlugin { public string AssemblyName; public string PrimaryEntity; public List Images; + public string UnsecureConfiguration; } public class MetaImage diff --git a/src/XrmMockup2011/XrmMockup2011.csproj b/src/XrmMockup2011/XrmMockup2011.csproj index 1a6649e1..1ff59424 100644 --- a/src/XrmMockup2011/XrmMockup2011.csproj +++ b/src/XrmMockup2011/XrmMockup2011.csproj @@ -78,7 +78,7 @@ --> - + True @@ -118,7 +118,7 @@ - + True @@ -144,7 +144,7 @@ - + ..\..\packages\crm2011\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/src/XrmMockup2013/XrmMockup2013.csproj b/src/XrmMockup2013/XrmMockup2013.csproj index a72c2095..98a77fbf 100644 --- a/src/XrmMockup2013/XrmMockup2013.csproj +++ b/src/XrmMockup2013/XrmMockup2013.csproj @@ -117,7 +117,7 @@ - + True @@ -187,7 +187,7 @@ - + True @@ -216,7 +216,7 @@ - + ..\..\packages\crm2013\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/src/XrmMockup2015/XrmMockup2015.csproj b/src/XrmMockup2015/XrmMockup2015.csproj index ad6a9ffc..ead65728 100644 --- a/src/XrmMockup2015/XrmMockup2015.csproj +++ b/src/XrmMockup2015/XrmMockup2015.csproj @@ -64,7 +64,7 @@ --> - + True @@ -104,7 +104,7 @@ - + True @@ -133,7 +133,7 @@ - + ..\..\packages\crm2015\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/src/XrmMockup2016/XrmMockup2016.csproj b/src/XrmMockup2016/XrmMockup2016.csproj index aa97cb0d..d270d5bf 100644 --- a/src/XrmMockup2016/XrmMockup2016.csproj +++ b/src/XrmMockup2016/XrmMockup2016.csproj @@ -65,7 +65,7 @@ --> - + True @@ -105,7 +105,7 @@ - + True @@ -134,7 +134,7 @@ - + ..\..\packages\crm2016\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/src/XrmMockup365/XrmMockup365.csproj b/src/XrmMockup365/XrmMockup365.csproj index 1f26e13a..2f8f2083 100644 --- a/src/XrmMockup365/XrmMockup365.csproj +++ b/src/XrmMockup365/XrmMockup365.csproj @@ -63,7 +63,7 @@ --> - + True @@ -103,7 +103,7 @@ - + True @@ -132,7 +132,7 @@ - + ..\..\packages\crm365\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/src/XrmMockupShared/Core.cs b/src/XrmMockupShared/Core.cs index 97ffd7ca..32323074 100644 --- a/src/XrmMockupShared/Core.cs +++ b/src/XrmMockupShared/Core.cs @@ -166,6 +166,8 @@ private void InitializeDB() new RetrievePrincipalAccessRequestHandler(this, db, metadata, security), }; + + internal void EnableProxyTypes(Assembly assembly) { foreach (var type in assembly.GetLoadableTypes()) @@ -592,6 +594,11 @@ internal void AddWorkflow(Entity workflow) workflowManager.AddWorkflow(workflow); } + internal void AddCodeActivityTrigger(Type type) + { + workflowManager.AddCodeActivityTrigger(type); + } + internal bool ContainsEntity(Entity entity) { var dbentity = db.GetEntityOrNull(entity.ToEntityReference()); @@ -706,10 +713,10 @@ internal void DisabelRegisteredPlugins(bool include) pluginManager.DisabelRegisteredPlugins(include); } - internal void RegisterAdditionalPlugins(IEnumerable basePluginTypes, PluginRegistrationScope scope) + internal void RegisterAdditionalPlugins(IEnumerable basePluginTypes, PluginRegistrationScope scope,StepDerivationType stepDerivationType) { foreach (var type in basePluginTypes) - pluginManager.RegisterAdditionalPlugin(type, metadata.EntityMetadata, metadata.Plugins, scope); + pluginManager.RegisterAdditionalPlugin(type, metadata.EntityMetadata, metadata.Plugins, scope, stepDerivationType); } internal void TakeSnapshot(string snapshotName) diff --git a/src/XrmMockupShared/Database/XrmDb.cs b/src/XrmMockupShared/Database/XrmDb.cs index e8299369..3e79a1e8 100644 --- a/src/XrmMockupShared/Database/XrmDb.cs +++ b/src/XrmMockupShared/Database/XrmDb.cs @@ -1,6 +1,7 @@ using Microsoft.Xrm.Sdk; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Text; using System.Linq; using System.ServiceModel; @@ -126,8 +127,11 @@ internal DbRow GetDbRow(EntityReference reference, bool withReferenceCheck = tru } } if (currentDbRow == null) { - throw new FaultException($"The record of type '{reference.LogicalName}' with id '{reference.Id}' " + - "does not exist. If you use hard-coded records from CRM, then make sure you create those records before retrieving them."); + Trace.WriteLine($"The record of type '{reference.LogicalName}' with id '{reference.Id}' " + + "does not exist. If you use hard-coded records from CRM, then make sure you create those records before retrieving them."); + return null; + //throw new FaultException($"The record of type '{reference.LogicalName}' with id '{reference.Id}' " + + // "does not exist. If you use hard-coded records from CRM, then make sure you create those records before retrieving them."); } } @@ -157,15 +161,16 @@ internal DbRow GetDbRow(Entity xrmEntity) { internal DbRow GetDbRow(string logicalName, Guid id) { - return GetDbRow(new EntityReference(logicalName, id)); + var row = GetDbRow(new EntityReference(logicalName, id)); + return row; } public Entity GetEntity(string logicalName, Guid id) { - return GetDbRow(logicalName, id).ToEntity(); + return GetDbRow(logicalName, id)?.ToEntity(); } public Entity GetEntity(EntityReference reference) { - return GetDbRow(reference).ToEntity(); + return GetDbRow(reference)?.ToEntity(); } diff --git a/src/XrmMockupShared/Plugin/Plugin.cs b/src/XrmMockupShared/Plugin/Plugin.cs index c4340a94..8fae436e 100644 --- a/src/XrmMockupShared/Plugin/Plugin.cs +++ b/src/XrmMockupShared/Plugin/Plugin.cs @@ -165,13 +165,16 @@ public void Execute(IServiceProvider serviceProvider) { ) select a.Item4).FirstOrDefault(); - if (entityAction != null) { - localcontext.Trace(string.Format( + if (entityAction != null) + { + var message = string.Format( CultureInfo.InvariantCulture, "{0} is firing for Entity: {1}, Message: {2}", this.ChildClassName, localcontext.PluginExecutionContext.PrimaryEntityName, - localcontext.PluginExecutionContext.MessageName)); + localcontext.PluginExecutionContext.MessageName); + localcontext.Trace(message); + Console.WriteLine(message); try { entityAction.Invoke(localcontext); diff --git a/src/XrmMockupShared/Plugin/PluginManager.cs b/src/XrmMockupShared/Plugin/PluginManager.cs index cf691e88..c3e484df 100644 --- a/src/XrmMockupShared/Plugin/PluginManager.cs +++ b/src/XrmMockupShared/Plugin/PluginManager.cs @@ -39,11 +39,11 @@ public PluginManager(IEnumerable basePluginTypes, Dictionary>>(); registeredSystemPlugins = new Dictionary>>(); - RegisterPlugins(basePluginTypes, metadata, plugins, registeredPlugins); + RegisterPlugins(basePluginTypes, metadata, plugins, registeredPlugins,StepDerivationType.BASECLASS); RegisterSystemPlugins(registeredSystemPlugins); } - private void RegisterPlugins(IEnumerable basePluginTypes, Dictionary metadata, List plugins, Dictionary>> register) + private void RegisterPlugins(IEnumerable basePluginTypes, Dictionary metadata, List plugins, Dictionary>> register, StepDerivationType stepDerivationType) { foreach (var basePluginType in basePluginTypes) { @@ -53,60 +53,183 @@ private void RegisterPlugins(IEnumerable basePluginTypes, Dictionary metadata, List plugins, Dictionary>> register) + + + public class StepRegistration { - var plugin = Activator.CreateInstance(basePluginType); + public StepConfig StepConfig { get; private set; } + public ExtendedStepConfig ExtendedStepConfig { get; private set; } + public IEnumerable ImageTuples { get; private set; } + public Action PluginExecuteMethod { get; private set; } - Action pluginExecute = null; - var stepConfigs = new List>>(); + public StepRegistration(StepConfig stepConfig, ExtendedStepConfig extendedStepConfig, IEnumerable imageTuples, Action pluginExecuteMethod) + { + StepConfig = stepConfig; + ExtendedStepConfig = extendedStepConfig; + ImageTuples = imageTuples; + PluginExecuteMethod = pluginExecuteMethod; + } + + } - if (basePluginType.GetMethod("PluginProcessingStepConfigs") != null) - { // Matches DAXIF plugin registration - stepConfigs.AddRange( - basePluginType - .GetMethod("PluginProcessingStepConfigs") - .Invoke(plugin, new object[] { }) - as IEnumerable>>); - pluginExecute = (provider) => { - basePluginType - .GetMethod("Execute") - .Invoke(plugin, new object[] { provider }); - }; + private void RegisterPlugin(Type basePluginType, Dictionary metadata, List plugins, Dictionary>> register, StepDerivationType stepDerivationType) + { + object plugin = null; + var constructors = basePluginType.GetConstructors(); + //is there a parameterless constructor + bool hasParameterlessConstructor = false; + bool hasTwoStringConstructor = false; + bool hasOneStringConstructor = false; + foreach (ConstructorInfo constructorInfo in constructors) + { + var parameters = constructorInfo.GetParameters(); + if (parameters.Length == 0) + { + hasParameterlessConstructor = true; + } + if (parameters.Length == 1) + { + if (parameters[0].ParameterType.Equals(typeof(String))) + { + hasOneStringConstructor = true; + } + } + else if (parameters.Length == 2) + { + //are they both string + if(parameters[0].ParameterType.Equals(typeof(String)) && + parameters[1].ParameterType.Equals(typeof(String))) + { + hasTwoStringConstructor = true; + } + } + } + //is there a constructor that takes two stirntgs, as it will be for the configuration + if (!hasOneStringConstructor && !hasTwoStringConstructor && hasParameterlessConstructor) + { + plugin = Activator.CreateInstance(basePluginType); } - else - { // Retrieve registration from CRM metadata + + else if (!hasParameterlessConstructor && !hasOneStringConstructor && !hasTwoStringConstructor) + { + throw new Exception( + "Plugin does not have either a parameterless constructor or a construcor that takes two config strings"); + } + + + + //Action pluginExecute = null; + + //var stepConfigs = new List>>(); + + var stepConfigs = new List(); + + if (stepDerivationType == StepDerivationType.BASECLASS || stepDerivationType==StepDerivationType.BOTH) + { + if (basePluginType.GetMethod("PluginProcessingStepConfigs") != null) + { // Matches DAXIF plugin registration + + if (hasOneStringConstructor) + { + //activate plugin, passing in unsecure and secure configs as parameters. currently, these are null when not being drived from the metadata directly. + plugin = Activator.CreateInstance(basePluginType, ""); + } + else if (hasTwoStringConstructor) + { + //activate plugin, passing in unsecure and secure configs as parameters. currently, these are null when not being drived from the metadata directly. + plugin = Activator.CreateInstance(basePluginType, "", ""); + } + + Action pluginExecute = (provider) => { + basePluginType + .GetMethod("Execute") + .Invoke(plugin, new object[] { provider }); + }; + + + var sc = basePluginType.GetMethod("PluginProcessingStepConfigs").Invoke(plugin, new object[] { }) + as IEnumerable>>; + foreach (var item in sc) + { + StepConfig stepconfig = item.Item1; + ExtendedStepConfig exstepconfig = item.Item2; + IEnumerable imagetuplelist = item.Item3; + + StepRegistration stepReg = new StepRegistration(stepconfig,exstepconfig,imagetuplelist,pluginExecute); + + stepConfigs.Add(stepReg); + } + + //stepConfigs.AddRange(basePluginType.GetMethod("PluginProcessingStepConfigs").Invoke(plugin, new object[] { })as IEnumerable>>); + + } + else + { + stepDerivationType = StepDerivationType.METADATA; //fallback to trying to get plugin steps from metadata instead + } + } + + if (stepDerivationType == StepDerivationType.METADATA || stepDerivationType == StepDerivationType.BOTH) + { + // Retrieve registration from CRM metadata var metaSteps = plugins.Where(x => x.AssemblyName == basePluginType.FullName).ToList(); - if (metaSteps == null || metaSteps.Count == 0) + if (metaSteps.Count == 0) { - throw new MockupException($"Unknown plugin '{basePluginType.FullName}', please use DAXIF registration or make sure the plugin is uploaded to CRM."); + Console.WriteLine($"Unknown plugin '{basePluginType.FullName}', no steps are registered in CRM and so this plugin will not be fired at any point. Please use DAXIF registration or make sure the plugin is uploaded to CRM."); } - foreach(var metaStep in metaSteps) { + foreach (var metaStep in metaSteps) + { var stepConfig = new StepConfig(metaStep.AssemblyName, metaStep.Stage, metaStep.MessageName, metaStep.PrimaryEntity); var extendedConfig = new ExtendedStepConfig(0, metaStep.Mode, metaStep.Name, metaStep.Rank, metaStep.FilteredAttributes, Guid.Empty.ToString()); var imageTuple = metaStep.Images?.Select(x => new ImageTuple(x.Name, x.EntityAlias, x.ImageType, x.Attributes)).ToList() ?? new List(); - stepConfigs.Add(new Tuple>(stepConfig, extendedConfig, imageTuple)); - pluginExecute = (provider) => { + //stepConfigs.Add(new Tuple>(stepConfig, extendedConfig, imageTuple)); + + if (hasOneStringConstructor) + { + //activate plugin, passing in unsecure and secure configs as parameters. currently, these are null when not being drived from the metadata directly. + plugin = Activator.CreateInstance(basePluginType, metaStep.UnsecureConfiguration); + } + else if (hasTwoStringConstructor) + { + //activate plugin, passing in unsecure and secure configs as parameters + plugin = Activator.CreateInstance(basePluginType,metaStep.UnsecureConfiguration,""); + } + + + Action pluginExecute = (provider) => { basePluginType - .GetMethod("Execute") - .Invoke(plugin, new object[] { provider }); + .GetMethod("Execute") + .Invoke(plugin, new object[] { provider }); }; + + StepRegistration stepReg = new StepRegistration(stepConfig, extendedConfig, imageTuple, pluginExecute); + stepConfigs.Add(stepReg); } } + + + // Add discovered plugin triggers foreach (var stepConfig in stepConfigs) { - var operation = (EventOperation)Enum.Parse(typeof(EventOperation), stepConfig.Item1.Item3); - var stage = (ExecutionStage)stepConfig.Item1.Item2; - var trigger = new PluginTrigger(operation, stage, pluginExecute, stepConfig, metadata); + //var operation = (EventOperation)Enum.Parse(typeof(EventOperation), stepConfig.Item1.Item3); + //var stage = (ExecutionStage)stepConfig.Item1.Item2; + //var trigger = new PluginTrigger(operation, stage, pluginExecute, stepConfig, metadata); + + var operation = (EventOperation)Enum.Parse(typeof(EventOperation), stepConfig.StepConfig.Item3); + var stage = (ExecutionStage)stepConfig.StepConfig.Item2; + + Tuple> stepConfigTuple = new Tuple>(stepConfig.StepConfig,stepConfig.ExtendedStepConfig,stepConfig.ImageTuples); + var trigger = new PluginTrigger(operation, stage, stepConfig.PluginExecuteMethod, stepConfigTuple, metadata); AddTrigger(operation, stage, trigger, register); } @@ -123,17 +246,17 @@ public void DisabelRegisteredPlugins(bool disable) disableRegisteredPlugins = disable; } - public void RegisterAdditionalPlugin(Type pluginType, Dictionary metadata, List plugins, PluginRegistrationScope scope) + public void RegisterAdditionalPlugin(Type pluginType, Dictionary metadata, List plugins, PluginRegistrationScope scope, StepDerivationType stepDerivationType) { - if (pluginType.GetMethod("PluginProcessingStepConfigs") == null) - throw new MockupException($"Unknown plugin '{pluginType.FullName}', please use the MockPlugin to register your plugin."); + //if (pluginType.GetMethod("PluginProcessingStepConfigs") == null) + // throw new MockupException($"Unknown plugin '{pluginType.FullName}', please use the MockPlugin to register your plugin."); if (scope == PluginRegistrationScope.Permanent) { - RegisterPlugin(pluginType, metadata, plugins, registeredPlugins); + RegisterPlugin(pluginType, metadata, plugins, registeredPlugins, stepDerivationType); } else if (scope == PluginRegistrationScope.Temporary) { - RegisterPlugin(pluginType, metadata, plugins, temporaryPlugins); + RegisterPlugin(pluginType, metadata, plugins, temporaryPlugins, stepDerivationType); } } diff --git a/src/XrmMockupShared/Utility.cs b/src/XrmMockupShared/Utility.cs index 1f07936a..97a3bc50 100644 --- a/src/XrmMockupShared/Utility.cs +++ b/src/XrmMockupShared/Utility.cs @@ -1261,4 +1261,15 @@ internal enum Opportunity_StatusCode OutSold = 5, } + [DataContract()] + public enum StepDerivationType + { + [EnumMember()] + BASECLASS =1, + [EnumMember()] + METADATA = 2, + [EnumMember()] + BOTH = 3 + } + } diff --git a/src/XrmMockupShared/Workflow/WorkflowManager.cs b/src/XrmMockupShared/Workflow/WorkflowManager.cs index 4ecb47d8..145580d2 100644 --- a/src/XrmMockupShared/Workflow/WorkflowManager.cs +++ b/src/XrmMockupShared/Workflow/WorkflowManager.cs @@ -172,6 +172,7 @@ private void ExecuteIfMatch(Entity workflow, EventOperation operation, Execution internal WorkflowTree ExecuteWorkflow(WorkflowTree workflow, Entity primaryEntity, PluginContext pluginContext, Core core) { var provider = new MockupServiceProviderAndFactory(core, pluginContext, new TracingService()); var service = provider.CreateAdminOrganizationService(new MockupServiceSettings(true, true, MockupServiceSettings.Role.SDK)); + Console.WriteLine("Executing Workflow (xml based):" + workflow.WorkflowName + " for entity: " + primaryEntity.LogicalName); return workflow.Execute(primaryEntity, core.TimeOffset, service, provider, provider.GetService(typeof(ITracingService)) as ITracingService); } @@ -204,6 +205,16 @@ internal void AddWorkflow(Entity workflow) { #endif } + internal void AddCodeActivityTrigger(Type type) + { + var codeActivity = (CodeActivity)Activator.CreateInstance(type); + + if (!codeActivityTriggers.ContainsKey(type.Name)) + { + codeActivityTriggers.Add(type.Name, codeActivity); + } + } + public Entity GetActionDefaultNull(string requestName) { return actions.FirstOrDefault(e => e.GetAttributeValue("name") == requestName); } @@ -214,5 +225,7 @@ internal void ResetWorkflows() { parsedWorkflows = new Dictionary(); waitingWorkflows = new List(); } + + } } diff --git a/src/XrmMockupShared/XrmMockupBase.cs b/src/XrmMockupShared/XrmMockupBase.cs index 6c2978d7..71cdcb60 100644 --- a/src/XrmMockupShared/XrmMockupBase.cs +++ b/src/XrmMockupShared/XrmMockupBase.cs @@ -174,6 +174,8 @@ public void AddTime(int days) { AddTime(new TimeSpan(days, 0, 0, 0)); } + + /// /// Increase the local time that mockup uses by an offset of days /// @@ -199,6 +201,15 @@ public void AddWorkflow(string path) { Core.AddWorkflow(workflow); } + /// + /// add a code activity trigger from a known type + /// + /// + public void AddCodeActivityTrigger(Type type) + { + Core.AddCodeActivityTrigger(type); + } + /// /// Returns true if an entity exists in the database with the same id, and has at least the attributes of the parameter. /// @@ -391,9 +402,137 @@ public void DisableRegisteredPlugins(bool include) /// /// The scope of the plugin registration /// - public void RegisterAdditionalPlugins(PluginRegistrationScope scope, params Type[] basePluginTypes) + public void RegisterAdditionalPlugins(PluginRegistrationScope scope, StepDerivationType stepDerivationType, params Type[] basePluginTypes) + { + Core.RegisterAdditionalPlugins(basePluginTypes, scope, stepDerivationType); + } + + /// + /// allows you to register additional workflow activities from a list of compiled assemblies, present at a given location + /// + /// + /// base types to match against eg. CodeActivity / AccountWorkflowActivity + /// + /// If yes, a type equality test is ignored in favour of checking the FullName properrty for equality instead. Useful if types are being loaded from ilmerged assemblies + public void RegisterWorkflowCodeActivitiesFromExternalAssemblies(string workFlowAssembliesPath, List matchingTypes, List filesToIgnore, bool matchOnTypeFullName = false) + { + if (!string.IsNullOrEmpty(workFlowAssembliesPath)) + { + var workflowTypes = GetLoadableTypesFromAssembliesInPath(workFlowAssembliesPath, matchingTypes, filesToIgnore, matchOnTypeFullName); + Console.WriteLine("Found " + workflowTypes.Count() + " Workflows to load from external assemblies"); + foreach (Type type in workflowTypes) + { + AddCodeActivityTrigger(type); + } + } + } + + /// + /// allows you to register additional plugin steps from a list of compiled assemblies, present at a given location + /// + /// + /// base types to match against eg. Plugin + /// + /// where to get the plugin step registrations from. either as part of the plugin hardcoded, or as part of the live crm metadata + /// If yes, a type equality test is ignored in favour of checking the FullName properrty for equality instead. Useful if types are being loaded from ilmerged assemblies + public void RegisterPluginsFromExternalAssemblies(string pluginAssembliesPath, List matchingTypes, List filesToIgnore, StepDerivationType stepDerivationType, bool matchOnTypeFullName = false) + { + if (!string.IsNullOrEmpty(pluginAssembliesPath)) + { + var pluginTypes = GetLoadableTypesFromAssembliesInPath(pluginAssembliesPath, matchingTypes,filesToIgnore, matchOnTypeFullName); + Console.WriteLine("Found " + pluginTypes.Count() + " Plugins to load from external assemblies"); + foreach (Type type in pluginTypes) + { + RegisterAdditionalPlugins(PluginRegistrationScope.Temporary, stepDerivationType, type ); + } + } + } + + private IEnumerable GetLoadableTypesFromAssembliesInPath(string path, List baseTypesAndInterfacesToLoad, List filesToIgnore, bool matchOnTypeFullName = false) { - Core.RegisterAdditionalPlugins(basePluginTypes, scope); + List types = new List(); + + List baseTypesToLoad = baseTypesAndInterfacesToLoad.Where(t => !t.IsInterface).ToList(); + List interfacesToLoad = baseTypesAndInterfacesToLoad.Where(t => t.IsInterface).ToList(); + + + try + { + DirectoryInfo d = new DirectoryInfo(path); + if (Directory.Exists(path)) + { + FileInfo[] Files = d.GetFiles("*.dll"); //get libraries + + foreach (FileInfo file in Files) + { + var isRestrictedFile = (filesToIgnore != null && filesToIgnore.Count > 0) && + filesToIgnore.Any(f => file.Name.IndexOf(f, StringComparison.Ordinal) > -1); + + if (!isRestrictedFile) + { + var assembly = Assembly.LoadFrom(file.FullName); + var allTypes = assembly.GetTypes(); + foreach (Type type in allTypes) + { + if (baseTypesToLoad.Any(ttl => ttl.FullName == type.FullName)) + { + //this type matches a base type so ignore it + continue; + } + + if (matchOnTypeFullName) + { + if (type.BaseType != null && baseTypesToLoad.Any(p => p.FullName == type.BaseType.FullName)) + { + //does it have an execute method? + var executeMethod = type.BaseType.GetMethod("Execute", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + if (executeMethod != null) + { + types.Add(type); + } + } + else if (type.GetInterfaces().Any(i => interfacesToLoad.Any(itl => itl.FullName == i.FullName))) //match against interfaces + { + //does it have an execute method? + + var executeMethod = type.GetMethod("Execute", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + if (executeMethod != null) + { + types.Add(type); + } + } + } + else + { + if (type.BaseType!=null && baseTypesToLoad.Any(p => p == type.BaseType)) + { + var executeMethod = type.BaseType.GetMethod("Execute", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + if (executeMethod != null) + { + types.Add(type); + } + } + else if (type.GetInterfaces().Any(i => interfacesToLoad.Any(itl => itl == i))) //match against interfaces + { + var executeMethod = type.GetMethod("Execute", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + if (executeMethod != null) + { + types.Add(type); + } + } + } + } + } + } + } + + + return types; + } + catch (ReflectionTypeLoadException e) + { + return e.Types.Where(t => t != null); + } } } diff --git a/src/XrmMockupWorkflow/WorkflowConstructor.cs b/src/XrmMockupWorkflow/WorkflowConstructor.cs index 3c7320be..276583e8 100644 --- a/src/XrmMockupWorkflow/WorkflowConstructor.cs +++ b/src/XrmMockupWorkflow/WorkflowConstructor.cs @@ -31,13 +31,15 @@ public static WorkflowTree Parse(Entity workflow, Dictionary a.Direction == WorkflowArgument.DirectionType.Input && !a.IsTarget).ToList(); var output = arguments.Where(a => a.Direction == WorkflowArgument.DirectionType.Output && !a.IsTarget).ToList(); - return new WorkflowTree(CompressTree(parsed.Workflow, parseAs), + var tree = new WorkflowTree(CompressTree(parsed.Workflow, parseAs), workflow.GetAttributeValue("triggeroncreate"), workflow.GetAttributeValue("triggerondelete"), triggerFields, workflow.GetOptionSetValue("runas"), workflow.GetOptionSetValue("scope"), workflow.GetOptionSetValue("createstage"), workflow.GetOptionSetValue("updatestage"), workflow.GetOptionSetValue("deletestage"), workflow.GetOptionSetValue("mode"), workflow.GetAttributeValue("ownerid").Id, workflow.GetAttributeValue("primaryentity"), codeActivites, input, output); + tree.WorkflowName = workflow.GetAttributeValue("name"); + return tree; } private static WorkflowArgument ConvertToArgument(Property p) { diff --git a/src/XrmMockupWorkflow/WorkflowTree.cs b/src/XrmMockupWorkflow/WorkflowTree.cs index f7aaf882..144ca5b9 100644 --- a/src/XrmMockupWorkflow/WorkflowTree.cs +++ b/src/XrmMockupWorkflow/WorkflowTree.cs @@ -74,6 +74,8 @@ internal class WorkflowTree { public List Input; [DataMember] public List Output; + [DataMember] + public string WorkflowName { get; set; } public WorkflowTree(IWorkflowNode StartActivity) : this(StartActivity, false, false, new HashSet(), @@ -104,6 +106,8 @@ public WorkflowTree(IWorkflowNode StartActivity, bool? TriggerOnCreate, bool? Tr this.Output = Output; } + + public WorkflowTree Execute(Entity primaryEntity, TimeSpan timeOffset, IOrganizationService orgService, IOrganizationServiceFactory factory, ITracingService trace) { if (primaryEntity.Id == Guid.Empty) { @@ -810,6 +814,11 @@ public void Execute(ref Dictionary variables, TimeSpan timeOffse return; } entity = orgService.Retrieve(EntityLogicalName, entRef.Id, new ColumnSet(true)); + + if (!variables.ContainsKey(EntityId)) + { + variables.Add(EntityId, entity); + } } else { entity = variables.ContainsKey(EntityId) ? variables[EntityId] as Entity : null; @@ -1549,11 +1558,23 @@ public void Execute(ref Dictionary variables, TimeSpan timeOffse arg => (outArguments.ContainsKey(arg.Value) ? null : variablesInstance[arg.Value])); var codeActivities = variables["CodeActivites"] as Dictionary; + + if (codeActivities==null || !codeActivities.ContainsKey(CodeActivityName)) + { + //cannot run the code activity! + Console.WriteLine("Cannot Execute '"+ CodeActivityName + "' workflow activity as it does not exist in the CodeActivities List. Have you registered it?"); + return; + } + + var codeActivity = codeActivities[CodeActivityName]; var primaryEntity = variables["InputEntities(\"primaryEntity\")"] as Entity; var workflowContext = new XrmWorkflowContext(); workflowContext.PrimaryEntityId = primaryEntity.Id; workflowContext.PrimaryEntityName = primaryEntity.LogicalName; + + Console.WriteLine("Executing Workflow Activity:" + CodeActivityName + " for entity: " + primaryEntity.LogicalName); + var invoker = new WorkflowInvoker(codeActivity); invoker.Extensions.Add(trace); invoker.Extensions.Add(workflowContext); diff --git a/tests/SharedTests/UnitTestBase.cs b/tests/SharedTests/UnitTestBase.cs index 0f738a6a..11abbdc6 100644 --- a/tests/SharedTests/UnitTestBase.cs +++ b/tests/SharedTests/UnitTestBase.cs @@ -1,15 +1,24 @@ using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Web.Configuration; +using System.Activities; using DG.Tools; using DG.Some.Namespace; using Microsoft.Xrm.Sdk; using Microsoft.VisualStudio.TestTools.UnitTesting; using DG.Tools.XrmMockup; using Microsoft.Xrm.Sdk.Client; +using Microsoft.Xrm.Sdk.Workflow; -namespace DG.XrmMockupTest { +namespace DG.XrmMockupTest +{ [TestClass] - public class UnitTestBase { + public class UnitTestBase + { private static DateTime _startTime { get; set; } protected IOrganizationService orgAdminUIService; @@ -33,27 +42,32 @@ public class UnitTestBase { protected static XrmMockup365 crmRealData; #endif - public UnitTestBase() { + public UnitTestBase() + { this.orgAdminUIService = crm.GetAdminService(new MockupServiceSettings(true, false, MockupServiceSettings.Role.UI)); this.orgGodService = crm.GetAdminService(new MockupServiceSettings(false, true, MockupServiceSettings.Role.SDK)); this.orgAdminService = crm.GetAdminService(); - if(crmRealData != null) + if (crmRealData != null) this.orgRealDataService = crmRealData.GetAdminService(); } [TestCleanup] - public void TestCleanup() { + public void TestCleanup() + { crm.ResetEnvironment(); } [AssemblyInitialize] - public static void InitializeServices(TestContext context) { + public static void InitializeServices(TestContext context) + { InitializeMockup(context); } - public static void InitializeMockup(TestContext context) { - var settings = new XrmMockupSettings { + public static void InitializeMockup(TestContext context) + { + var settings = new XrmMockupSettings + { BasePluginTypes = new Type[] { typeof(DG.Some.Namespace.Plugin), typeof(PluginNonDaxif) }, CodeActivityInstanceTypes = new Type[] { typeof(AccountWorkflowActivity) }, EnableProxyTypes = true, @@ -61,18 +75,37 @@ public static void InitializeMockup(TestContext context) { ExceptionFreeRequests = new string[] { "TestWrongRequest" }, }; + string workFlowAssembliesPath = WebConfigurationManager.AppSettings["CompiledWorkflowAssembliesPath"]; + var librariesToIgnore = new List() {"Microsoft."}; + + #if XRM_MOCKUP_TEST_2011 crm = XrmMockup2011.GetInstance(settings); #elif XRM_MOCKUP_TEST_2013 crm = XrmMockup2013.GetInstance(settings); + var customWorkflowTypes = new List() {typeof(CodeActivity)}; + crm.RegisterWorkflowCodeActivitiesFromExternalAssemblies(workFlowAssembliesPath, customWorkflowTypes, librariesToIgnore); #elif XRM_MOCKUP_TEST_2015 crm = XrmMockup2015.GetInstance(settings); + var customWorkflowTypes = new List() {typeof(CodeActivity)}; + crm.RegisterWorkflowCodeActivitiesFromExternalAssemblies(workFlowAssembliesPath, customWorkflowTypes, librariesToIgnore); #elif XRM_MOCKUP_TEST_2016 crm = XrmMockup2016.GetInstance(settings); + var customWorkflowTypes = new List() {typeof(CodeActivity)}; + crm.RegisterWorkflowCodeActivitiesFromExternalAssemblies(workFlowAssembliesPath, customWorkflowTypes, librariesToIgnore); #elif XRM_MOCKUP_TEST_365 crm = XrmMockup365.GetInstance(settings); + var customWorkflowTypes = new List() { typeof(CodeActivity) }; + crm.RegisterWorkflowCodeActivitiesFromExternalAssemblies(workFlowAssembliesPath, customWorkflowTypes, librariesToIgnore); #endif + string pluginAssembliesPath = WebConfigurationManager.AppSettings["CompiledPluginAssembliesPath"]; + crm.RegisterPluginsFromExternalAssemblies(pluginAssembliesPath,settings.BasePluginTypes.ToList(), librariesToIgnore,StepDerivationType.BASECLASS); + + + + + try { var realDataSettings = new XrmMockupSettings diff --git a/tests/TestPluginAssembly11/TestPluginAssembly11.csproj b/tests/TestPluginAssembly11/TestPluginAssembly11.csproj index c1d7d318..024ab5b2 100644 --- a/tests/TestPluginAssembly11/TestPluginAssembly11.csproj +++ b/tests/TestPluginAssembly11/TestPluginAssembly11.csproj @@ -79,7 +79,7 @@ --> - + ..\..\packages\crm2011\Microsoft.CrmSdk.CoreAssemblies\lib\net40\Microsoft.Crm.Sdk.Proxy.dll @@ -95,7 +95,7 @@ - + True @@ -121,7 +121,7 @@ - + ..\..\packages\crm2011\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/tests/TestPluginAssembly13/TestPluginAssembly13.csproj b/tests/TestPluginAssembly13/TestPluginAssembly13.csproj index d03f3153..663af13b 100644 --- a/tests/TestPluginAssembly13/TestPluginAssembly13.csproj +++ b/tests/TestPluginAssembly13/TestPluginAssembly13.csproj @@ -111,7 +111,7 @@ - + True @@ -181,7 +181,7 @@ - + True @@ -210,7 +210,7 @@ - + ..\..\packages\crm2013\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/tests/TestPluginAssembly15/TestPluginAssembly15.csproj b/tests/TestPluginAssembly15/TestPluginAssembly15.csproj index d3cac48d..45c190c2 100644 --- a/tests/TestPluginAssembly15/TestPluginAssembly15.csproj +++ b/tests/TestPluginAssembly15/TestPluginAssembly15.csproj @@ -58,7 +58,7 @@ --> - + True @@ -98,7 +98,7 @@ - + True @@ -127,7 +127,7 @@ - + ..\..\packages\crm2015\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/tests/TestPluginAssembly16/TestPluginAssembly16.csproj b/tests/TestPluginAssembly16/TestPluginAssembly16.csproj index da27b48a..578e23d9 100644 --- a/tests/TestPluginAssembly16/TestPluginAssembly16.csproj +++ b/tests/TestPluginAssembly16/TestPluginAssembly16.csproj @@ -58,7 +58,7 @@ --> - + True @@ -98,7 +98,7 @@ - + True @@ -127,7 +127,7 @@ - + ..\..\packages\crm2016\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/tests/TestPluginAssembly365/TestPluginAssembly365.csproj b/tests/TestPluginAssembly365/TestPluginAssembly365.csproj index a530dc21..b113c734 100644 --- a/tests/TestPluginAssembly365/TestPluginAssembly365.csproj +++ b/tests/TestPluginAssembly365/TestPluginAssembly365.csproj @@ -58,7 +58,7 @@ --> - + True @@ -98,7 +98,7 @@ - + True @@ -127,7 +127,7 @@ - + ..\..\packages\crm365\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/tests/XrmMockup11Test/XrmMockup11Test.csproj b/tests/XrmMockup11Test/XrmMockup11Test.csproj index 666ae2dc..808a52ff 100644 --- a/tests/XrmMockup11Test/XrmMockup11Test.csproj +++ b/tests/XrmMockup11Test/XrmMockup11Test.csproj @@ -148,7 +148,7 @@ --> - + True @@ -167,7 +167,33 @@ - + + + + True + + + True + + + True + + + True + + + True + + + ..\..\packages\crm2011\Microsoft.CrmSdk.Workflow\lib\net40\Microsoft.Xrm.Sdk.Workflow.dll + True + True + + + + + + ..\..\packages\crm2011\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/tests/XrmMockup11Test/paket.references b/tests/XrmMockup11Test/paket.references index 64c55303..74bd5547 100644 --- a/tests/XrmMockup11Test/paket.references +++ b/tests/XrmMockup11Test/paket.references @@ -1,3 +1,4 @@ group crm2011 Microsoft.CrmSdk.CoreAssemblies - Microsoft.IdentityModel \ No newline at end of file + Microsoft.IdentityModel + Microsoft.CrmSdk.Workflow \ No newline at end of file diff --git a/tests/XrmMockup13Test/XrmMockup13Test.csproj b/tests/XrmMockup13Test/XrmMockup13Test.csproj index 8b72c2e6..c27a60a9 100644 --- a/tests/XrmMockup13Test/XrmMockup13Test.csproj +++ b/tests/XrmMockup13Test/XrmMockup13Test.csproj @@ -182,7 +182,7 @@ - + True @@ -234,7 +234,63 @@ - + + + + True + + + True + + + True + + + True + + + True + + + True + + + ..\..\packages\crm2013\Microsoft.CrmSdk.Workflow\lib\net40\Microsoft.Xrm.Sdk.Workflow.dll + True + True + + + + + + + True + + + True + + + True + + + True + + + True + + + True + + + ..\..\packages\crm2013\Microsoft.CrmSdk.Workflow\lib\net45\Microsoft.Xrm.Sdk.Workflow.dll + True + True + + + + + + ..\..\packages\crm2013\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/tests/XrmMockup13Test/paket.references b/tests/XrmMockup13Test/paket.references index 60ff8fef..3e25b8d8 100644 --- a/tests/XrmMockup13Test/paket.references +++ b/tests/XrmMockup13Test/paket.references @@ -1,3 +1,4 @@ group crm2013 Microsoft.CrmSdk.CoreAssemblies - Microsoft.IdentityModel \ No newline at end of file + Microsoft.IdentityModel + Microsoft.CrmSdk.Workflow \ No newline at end of file diff --git a/tests/XrmMockup15Test/XrmMockup15Test.csproj b/tests/XrmMockup15Test/XrmMockup15Test.csproj index e0882ec3..fbfab646 100644 --- a/tests/XrmMockup15Test/XrmMockup15Test.csproj +++ b/tests/XrmMockup15Test/XrmMockup15Test.csproj @@ -122,7 +122,7 @@ --> - + True @@ -171,7 +171,36 @@ - + + + + True + + + True + + + True + + + True + + + True + + + True + + + ..\..\packages\crm2015\Microsoft.CrmSdk.Workflow\lib\net45\Microsoft.Xrm.Sdk.Workflow.dll + True + True + + + + + + ..\..\packages\crm2015\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/tests/XrmMockup15Test/paket.references b/tests/XrmMockup15Test/paket.references index fd368779..b352e65b 100644 --- a/tests/XrmMockup15Test/paket.references +++ b/tests/XrmMockup15Test/paket.references @@ -1,3 +1,4 @@ group crm2015 Microsoft.CrmSdk.CoreAssemblies - Microsoft.IdentityModel \ No newline at end of file + Microsoft.IdentityModel + Microsoft.CrmSdk.Workflow \ No newline at end of file diff --git a/tests/XrmMockup16Test/XrmMockup16Test.csproj b/tests/XrmMockup16Test/XrmMockup16Test.csproj index 55be3538..89768bdb 100644 --- a/tests/XrmMockup16Test/XrmMockup16Test.csproj +++ b/tests/XrmMockup16Test/XrmMockup16Test.csproj @@ -137,7 +137,7 @@ --> - + True @@ -186,7 +186,33 @@ - + + + + True + + + True + + + True + + + True + + + True + + + ..\..\packages\crm2016\Microsoft.CrmSdk.Workflow\lib\net452\Microsoft.Xrm.Sdk.Workflow.dll + True + True + + + + + + ..\..\packages\crm2016\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/tests/XrmMockup16Test/paket.references b/tests/XrmMockup16Test/paket.references index 7826dad6..87d46101 100644 --- a/tests/XrmMockup16Test/paket.references +++ b/tests/XrmMockup16Test/paket.references @@ -1,3 +1,4 @@ group crm2016 Microsoft.CrmSdk.CoreAssemblies - Microsoft.IdentityModel \ No newline at end of file + Microsoft.IdentityModel + Microsoft.CrmSdk.Workflow \ No newline at end of file diff --git a/tests/XrmMockup365Test/XrmMockup365Test.csproj b/tests/XrmMockup365Test/XrmMockup365Test.csproj index b78f8c1d..6ca27ad7 100644 --- a/tests/XrmMockup365Test/XrmMockup365Test.csproj +++ b/tests/XrmMockup365Test/XrmMockup365Test.csproj @@ -136,7 +136,7 @@ --> - + True @@ -185,7 +185,36 @@ - + + + + True + + + True + + + True + + + True + + + True + + + True + + + ..\..\packages\crm365\Microsoft.CrmSdk.Workflow\lib\net452\Microsoft.Xrm.Sdk.Workflow.dll + True + True + + + + + + ..\..\packages\crm365\Microsoft.IdentityModel\lib\net35\Microsoft.IdentityModel.dll diff --git a/tests/XrmMockup365Test/paket.references b/tests/XrmMockup365Test/paket.references index 4cadb0cc..668d23f3 100644 --- a/tests/XrmMockup365Test/paket.references +++ b/tests/XrmMockup365Test/paket.references @@ -1,3 +1,4 @@ group crm365 Microsoft.CrmSdk.CoreAssemblies - Microsoft.IdentityModel \ No newline at end of file + Microsoft.IdentityModel + Microsoft.CrmSdk.Workflow \ No newline at end of file