A Scaled out CRM Solution Architecture

Recently I started work on a pretty big CRM project and I wanted to apply a more scaled out approach to my solution architecture.  CRM offers a great facility to deploy code in their solutions but when starting a new project you should always ask yourself the following questions before you starting adding entities into your solutions.

  1. What is the frequency of updates that will be requested by the users and to what components?
  2. Are there multiple users contributing to this project?
  3. How big do you expect this project to grow by?
  4. What kind of promotional model is in place for deployments?

I  have found that questions such as these generally drive the overall solution architecture I will put in place on a project.  For instance, if we are working with a client that has a Development to Production promotion model with only a developer or two on the project, I’ll suggest deploying as one solution.  However, if the project is quite large, has multiple developers on it coupled with multiple deployment stages (which invariably means a more formalized testing process) I’ll tend to go with a more scaled out architecture.

For this current project I went with a component based solution architecture broken out as follows;

  1. Entities – this contains all my core entities, client extensions and web resources.
  2. Security – this contains all my security roles.
  3. Reports – this contains all my custom reporting files.
  4. Workflows – this contains all custom workflows and plugin functionality.

The reason for this approach is to reduce the load on QA and allow the team to install what they need without fear of interfering with the work of others.


Some scenario examples where this should help the team;

  1. When a developer makes a change to only 1 of the solutions, QA can rest easy deploying that single solution (instead of all 4) and not having to regression test all 4 but only 1 solution.
  2. Reports will most likely be handled by developers that are very familiar with developing custom RDL files, as such, they don’t need references to any of the underlying entities and based on user feedback, they will be able to deploy on their own schedule, outside of the core application.
  3. Having security in it’s own solution now opens this up to being managed by non-developer groups (huge).  Although I don’t recommend deploying an unmanaged solution to Production, this solution can actually start it’s “development” or “work” in a TEST or UAT where Business Analysts can create the security roles they think make sense against the new components built by the developer teams without worrying about interfering with any previous development to date.

These are only a few scenarios where I see this architecture helping out in the long-run.  I have gone through a couple of iterations of scaled out architectures from feature to product based but so far this one represents a consistent approach that can be replicated across projects.

My next step will be to minimize any complexity associated with deploying updates to different environments by writing a little component to deploy the correct solution in the correct order.  However as it stands right now, the solutions themselves are quite loosely coupled and can be deployed without error (i.e., reports) without triggering a solution import error.

Using Dynamics365 as a Queue for Data Synchronization

Over the years, I’ve migrated a lot of data from on-premise systems into Dynamics365 (whether they be existing CRM system, homegrown solutions or off the shelf packages).  I’ve used a number of third-party tools to accomplish these tasks (Scribe and Kingsway) but have also written my own when the need arose.

On a recent project, faced with yet more synchronization requests and the need for more infrastructure to manage changes, mediate conflicts, prevent ping-ponging data writes, etc, etc.  I started to change my thinking from being able to have everything on-premise (i.e., the ability to queue up new Virtual Images and tons of server space et al) to think of how I solve this problem if all I had was Dynamics365 and the server I am moving data from.

To start with – how could I keep up-to-date with all the changes happening in Dynamics and queue them up for later retrieval by some other system.

My first thought was an async workflow to do the job but this raised up a few other requirements in doing this;

  1. Administrators should be able to associate this workflow to any new entity they want synced with super ease (i.e., create workflow, finish).
  2. The code for the workflow should not need to be modified at all and should dynamically figure out the entity and primary key attribute that I need to later retrieve to be synced.
  3. Code should be small.

So here is what I wrote as a workflow and then deployed to my online tenant.  The solution is really tiny, I created an entity called syn_dataeventqueue, which contains all the synchronization entries.

I did some tests between custom and core entities and was able to detect the proper change events coming in and for the correct entities.  You can see the initial state is “Not Processed” – I created some custom states for when I pull the requests to not pull again if the syncing period went longer than expected but that’s for another post – here is the code.

 protected override void Execute(CodeActivityContext Execution)
 //Get the Tracing Service
 ITracingService tracingService = Execution.GetExtension<ITracingService>();

 //get context
 IWorkflowContext context = Execution.GetExtension<IWorkflowContext>();
 //create iorganization service object
 IOrganizationServiceFactory serviceFactory = Execution.GetExtension<IOrganizationServiceFactory>();
 IOrganizationService service = serviceFactory.CreateOrganizationService(context.InitiatingUserId);

 //Now we need to query the entity for their primary id.
 RetrieveEntityRequest request = new RetrieveEntityRequest();
 request.EntityFilters = EntityFilters.Attributes;
 request.LogicalName = context.PrimaryEntityName;

 RetrieveEntityResponse response = (RetrieveEntityResponse)service.Execute(request);
 AttributeMetadata PrimaryAttribute = response.EntityMetadata.Attributes.Where(a => a.IsPrimaryId == true && a.AttributeType == AttributeTypeCode.Uniqueidentifier && a.ColumnNumber == 1).FirstOrDefault();
 string AttributeName = PrimaryAttribute.SchemaName.ToLower();

 Entity EntityToSync = (Entity)service.Retrieve(context.PrimaryEntityName, context.PrimaryEntityId, new ColumnSet(AttributeName));

 tracingService.Trace("Trace| Record to Synchronize: Entity [{0}], Id [{1}].", context.PrimaryEntityId.ToString(), context.PrimaryEntityName.ToString());

 if (EntityToSync.Contains(AttributeName))
 Entity SyncroEntity = new Entity("syn_dataeventqueue");
 SyncroEntity["syn_name"] = context.PrimaryEntityName;
 SyncroEntity["syn_entityrecordid"] = context.PrimaryEntityId.ToString();
 catch (Exception ex)
 tracingService.Trace("Error| Synchronization Submission Exception: {0}", ex.ToString());

The only piece you are probably wonder about is the search for ColumnNumber to be 1.  In my tests, this is always the primary id field, when I tried searching for simply the IsPrimaryId it brought back results for the primary ids of related entities so that didn’t work.

Here is how things look in the workflow creation itself.


One step!

And what does it look like in Dynamics?


Beautiful – now to finish the rest of it.


Setting up Dynamics365 for the First Time

I recently went down the path of purchasing a Microsoft Action Pack so immediately went to setting it up in my pre-existing Office365 Tenant and ran into a few gotchas that might save you some time.

Office365 Business Essentials and Enterprise Plan 1 Licensing

I currently have an Office365 Business Essentials plan but when creating my Dynamics tenant quick realized that my users that were licensed under my Business Essentials license cannot be readily imported into Dynamics365 due to SharePoint plan conflicts.

There is a path to upgrade users through the Office365 Admin, but that’s for another blog.

Setting up Dynamics365

When creating your tenant for Dynamics, it’s not solely about your licenses, but also about creating the actual tenant.  To do this, you need to first navigate down to the Settings section of your Office365 Admin and select “Services & Add-Ins”.  From there you will be presented with the window below where you now create your new tenant simply by clicking “Manager your Dynamics 365 settings”.


From there you will be prompted to go through the same steps that you generally go through when deploying a tenant (perhaps with a different User Interface).


In the above screenshot, I have configured my first tenant to be a Sandbox where I can do my development and mess around with things.  Sandboxes were always there before but are now included with every plan, irrespective of your plan, granting you one free sandbox per client.


As you can see in the above screenshot, my tenant is now listed as a Sandbox and not Production.

Now we can get to doing some coding.