This article will give you a step by step walk through of getting started with Dynamics 365 plugin development based on
the Kipon.Solid framework. This article assume you are familar with Visual Studio. This guide has NOT been design for
Visual Studio Code. Use the Community, Professional or Enterprise edition instead. The first one
is free and can be downloaded from here:
Download visual studio
The first thing to do is to open Visual Studio, and create a blank solution:
Provide a name and hit Create:
You now have an empty solution
Right click on the Solution line in the solution explore to add a .NET Framework project.
Give your plugin an appropriate name, and select .NET version 4.6.2. For now, that is the highest version supported by the Dynamics 365 CE Online platform, so don't take it higher than that for now. We will try to keep this info updated as the Dynamics 365 platform is moving forward. Push the Create button when you are ready:
Now your solution has the a .NET Framework class library. Just delete the Default Class1.cs. I never understood why that was added. Everbody is deleting it as the first action in a new project.
Now go to Tools > NuGet
Navigate to the Browse tab, search for Kipon.Solid.Plugin. Select your library and click Install.
Click Ok, and Accept in the popup's from the install project.
This installation has prepared both the needed Microsoft SDK tools for Dynamics 365 CE plugin development, and the tooles related to the Kipon.Solid framework.
After install the Kipon.Solid nuget package, a Kipon folder has been added to your solution. Just keep it there. The source code that creates the magic of the framework is in there, as source code, due to the single assembly constrain when deploying plugins to Dynamics 365. You must keep all the files in the Kipon folder as part of the solution, first of all for the solution to work, but also to be confirm to the license terms of the framework.
To take full advantage of the Kipon Solid plugin framework, you need strongly typed objects to represent your datatype. For this we will use the crmsvcutil tool provided by the Microsoft SDK, but the tool has been extended with new cababilities, so please follow below process to configure and generate strongly typed proxy classes for the entities you need:
You project now have a folder called "Entities":
As you can see, two files has been added to the entities directory. copy both files to new files in same folder, but without ".template" suffix. This suffix has been added to avoid the files to be overridden, and at same time enable easy distribution of working configuration examples. Create a copy instead of rename so you have the template file for later easy reference when you need to add different type of functionality later.
<filter supress-mapped-standard-optionset-properties="true"> <entities> <entity servicename="Accounts" logicalname="account"> <optionset logicalname="preferredcontactmethodcode" name="PreferredContactMethodCode"> <value name="Any">1</value> <value name="Email">2</value> <value name="Phone">3</value> <value name="Fax">4</value> <value name="Mail">5</value> </optionset> <optionset id="budget" logicalname="new_multiselectbudget" name="MultiSelectBudget"/> </entity> <entity servicename="Contacts" logicalname="contact"></entity> <entity servicename="Opportunities" logicalname="opportunity"> <optionset id="budget" logicalname="budgetstatus" name="Budgetstatus" /> </entity> <entity servicename="Quotes" logicalname="quote"></entity> <entity servicename="Salesorders" logicalname="salesorder"></entity> <entity servicename="Systemusers" logicalname="systemuser"></entity> </entities> <optionsets> <optionset id="budget" name="BudgetEnum"> <value name="NoCommittedBudget">0</value> <value name="MAyBuy">1</value> <value name="CanBuy">2</value> <value name="WillBuy">3</value> </optionset> </optionsets> <actions> <action name="AccountCountContacts">kipon_AccountCountContacts</action> </actions> </filter>
The template file need to be adjusted. it has been setup to demonstrate the capabilities of the Kipon.Solid framework. There are 3 main sections in the xml file <entities> to define the part of the CRM datamodel we need to work with, <optionsets> to map global optionsets to enums in the code, and finally <actions> to get interfaces and response proxy classes to listen to Dynamics 365 Actions. To get details on these elements, please refer to the Api section. For now, we will just reduce the configuration to a minimum to get started:
<filter supress-mapped-standard-optionset-properties="true"> <entities> <entity servicename="Accounts" logicalname="account"></entity> </entities> </filter>
With above configuration in place, as a file name "filter.xml" in the Entities folder, we are now ready to prepare the proxy generate tool. You have already renamed the generate.cmd.template file to "generate.cmd". Open this file, and search for "[Set ...]" and insert appropriate values.
- [Set connectionstring]: Insert appropriate connection string to your Dynamics 365 CE developer instance.
- [Set context Name]: You can name your Dynamics 365 entity model context. If you work 100% SOLID, according to the princips defined, you will never work directly on the generated context. You will instead work on unit-of-work interfaces, so the name is not important.
- [Set namespace]: Insert appropriate namespace for you library.
To see how you build up the connection string for your instance, you can diig deep in in this article:
Dynamics 365 CE connection strings
This is the result for my on-prem example development instance:
@echo off ..\bin\coretools\CrmSvcUtil.exe "/connectionstring:AuthType=AD;Url=http://kipon-dev/kip;" "/out:Context.design.cs" "/ServiceContextName:PluginExampleContextService" "/namespace:Kipon.PluginExample.Entities" "/codewriterfilter:Kipon.Xrm.Tools.CodeWriter.CodeWriterFilter,Kipon.Xrm.Tools" "/codecustomization:Kipon.Xrm.Tools.CodeWriter.PluginCustomizeCodeDomService,Kipon.Xrm.Tools" /generateActions
Now open a command prompt, navigate to the directory where the generate.cmd file is hosted, and start the generate.cmd
The tool should generate something like above.
This tool has added two files to the Entities directory that you need to include in your Visual Studio solution:
Select the two files, right click, and select include in project
You are ready.
You are ready to start build plugins. Try build your solution to make sure everything is in place. There should be no errors.
To start SOLID and stay SOLID, it is a good idea to get a basic structure for your code in place first. The Kipon.Solid framework has already giving you the first part of the structure, the "Entities" folder, where you should put code that are directly related to the Dynamics 365 CE entity model. All entity proxy classes has been generated as "partial" so you can add additional functionality by creating your own source files, and declare the same classes "again", with the partial flag in the class definition. Such extension of an entity should be placed in the Entities folder or in a substructure below the Entities folder depending on the size of your library
Beside the Entities folder, i recommend the following basic structure
- Models: Put cross entity interfaces and abstractions here. A model class in a Dynamics 365 plugin context is typicall an interface that defines the explicit hooks that are needed on the underlying entity to solve a task.
- Plugins: Here you should put your plugins. A plugin is the code that maps from an event to a service. If you plan to do a lot of plugins, create a folder for each entity and each action to listen for.
- ServiceAPI: Put all service interfaces here. Remember, to stay SOLID, all dependencies should rely on abstractions and interfaces, not on implementations. In this folder you define the interfaces that is needed to solve an assignment.
- Services: Projects developed with SOLID princips as foundation will often put interfaces in one assembly, while implementation in another. Due to the single assembly constrain on Dynamics 365 plugins, such helthy pattern is not an option, without adding messy deployment tool like ILMerge. Instead i place all service implementation in its own folder "Services". And then the project team need to follow the simple rule, that NOT DIRECT REFERECES to anything in the Services folder is allowed. The intention of the Services folder is to implement services defined by the ServiceAPI. Nothing else.
© Kipon ApS 2020, 2021, 2022. All content on the page is the property of Kipon ApS. Any republish or copy of this content is a violation. The content of this
site is NOT open source, and cannot be copied, republished or used in any context without explcit permission from the owner.