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