Today we will talk about how the company built team development on the MS Dynamics CRM platform. This platform, like most proprietary systems without source code, carries with it a number of limitations and additional difficulties for developers. System configuration, creation of internal entities, creation of UI - all this is implemented by the internal means of the platform, while there is no internal language, the ability to transfer settings is limited to uploading in an internal, undocumented format.
From a technical point of view, MS Dynamics CRM is a platform, which in most cases is used as a basis for the development of CRM and front-end solutions for small and medium-sized organizations. MS Dynamics CRM provides out of the box implementation of the typical blocks of such systems, which significantly speeds up development based on it. Using web services, workflows, writing custom plugins, client extensions, reports based on MS Dynamics CRM, coupled with an already implemented and debugged data model, role model, logging and other typical mechanisms, make it possible not to waste time on reproducing these blocks from implementation to implementation . Allows you to immediately focus directly on the implementation of the business functionality.
But these features have their price (besides the cost of licenses). And this price, as usual, is in the opacity of the boxed solution. Developers who grew up on classical software development are accustomed to the fact that there is absolute control over what is being developed. Those. there must be a complete source code of the product and the ability to turn it into an installation package (project build scripts) for deployment on a clean contour (installed from the system box).
Consider what options there are a team of 10+ developers to develop the functionality of an enterprise-scale system built on the basis of MS Dynamics CRM. By development we mean not only the ability to change the behavior of the system - this task is quite obvious and does not present any difficulty even with the proprietary system MS Dynamics CRM. We are interested in team development, the ability to simultaneously change the behavior of the system in terms of all components, the construction of Continuous Integration, the implementation of auto-assembly, and the final mechanization of Continuous Deployment without loss in speed and quality of people.
')
Let's start with an excursion into what is included in the concept of development under MS Dynamics CRM.
The main parts of the system based on MS Dynamics CRM from the point of view of the developer:
1) Settings (hereinafter we will call them Customization)
a. Plugins
b. Directories
c. Web resources
d. Reports
2) Auxiliary database objects
Immediately we will make a reservation that individually considered Plug-ins, Directories, Web resources, Reports are essentially parts of Customization, physically included in it. But we, from the point of view of development, consider them separately, since their life cycle in the development process varies significantly.
Plugin - implemented on C # logic triggered by an event. From a development point of view, this is a private class that implements IPlugin and compiled into a DLL.
Registration and setup of the trigger in the system is carried out by means of MS Dynamics CRM and is part of Customization.

Directories. In MS Dynamics CRM, a large amount of reference data is often used; often, the business logic of the system is rigidly tied to them. References refer to immutable entities with reference data sets. We have the usual system entities that do not change in the process of work, but change in the process of development. Incorrect data in reference books lead to unpredictable consequences. It is important to be able to control the consistency of their contents. The main tool here may be the versioning of changes in their contents.
Web resources are virtual files (JScript, CSS, XML, XSL, HTML, JPG, etc.) that can be used to extend MS Dynamics CRM forms. They are not stored in the web server directory, but in the form of virtual files in MS Dynamics CRM database. Each web resource has a unique name that can be used in the URL to retrieve the corresponding file. Their use is limited to feedback to the browser, server processing is not provided. During development, they are loaded using MS Dynamics CRM and become part of Customization.
Customization - settings of different components of MS Dynamics CRM system combined into one container. The development and adjustment of the functioning of the system is carried out by “programming with the mouse” in the internal editor of the system. It is possible to create Entities and their fields (Field), customize Workflow (a set of rules run on demand or automatically), create forms (Form) for the user to work with system entities and views (Views). All this together is called customization. Customization can be exported from the organization where it is being edited and imported into another organization within a single instance of the system or to another server.
(Organization in MS Dynamics CRM is a kind of sandbox within the system. Several organizations can work in parallel on one server, they are independent of each other, but each has its own base).
Auxiliary database objects. Often, when designing a system, you need to have your own objects (tables, views, stored procs, etc.) in the MS Dynamics CRM database or in the vicinity of a separate database. This is often done for storing and processing unknown MS Dynamics CRM data, importing it into the MS Dynamics CRM database using API or directly into the database (which is not welcome).
Reports. MS Dynamics CRM is integrated with MS SQL and Reporting Services. From the point of view of development, MS Dynamics CRM reports are a design template and information about data sources packed into a report template file.
The components outlined above are the main ones from the developer's point of view; it is them that he will rule creating a new system on the MS Dynamics CRM platform.
Obviously, of the above components, “problematic” is customization. This is a component of the system that does not have “source code” explicitly.
Referring to the recommendations of Microsoft on the organization of the development process under MS Dynamics CRM. Microsoft
offers 3 options:
• One organization: Single master solution
• One organization: Master solution + multiple change solutions
• Separate organization for each developer
The essence of the first two approaches comes down to development on a common Organization (several independent organizations can be deployed within a single instance of MS Dynamics CRM). An organization has created a single CRM solution (master solution) containing all customizable components, developers customize as part of this solution (in the second version, developers can create a separate solution for editing the components assigned to it). Ultimately, all changes to the final solution are exported by one person in charge after all the developers have completed work on their tasks. This fairly straightforward and simple approach harbors many problems:
- developers can overwrite each other's edits (for example, developers have opened the same form and changed it, the last one who posted the changes to the first one);
- if some kind of customization contains errors, then at the time of preparing the package it is necessary to roll back these changes (or make a stub) so that these changes do not go into the installation package, and this becomes quite time-consuming;
- only the package of tasks that were worked out by the person responsible for assembly / export can be transferred to testing. Those. Code changes for tasks are combined into a virtual container and become inseparable from each other, which entails an increase in testing time and exclusion of any tasks from the package. In addition, there are difficulties in separating solution components between developers — it is often necessary to edit the same components in different tasks.
The third approach “Separate Organization for each developer” is closest to the classical requirements for team development.
Each developer is supposed to “live” in his own separate Organization. To accomplish tasks, the developer imports the latest version of Customization (previously exports it from the Master Organization) to his organization. Then he makes the necessary changes to his tasks within his Organization. After that, it unloads the modified solution from its Organization, imports it into the Master Organization, from where the final sprint / release package is already being formed.
But even this approach does not solve all problems. Developers at the same time “live” on one server, which negatively affects the ability to fully debug their changes, it is not clear how to resolve conflicts.
What did we do
The first thing the developer needs is the ability to fully local debugging. Those. in other words, a developer should have access to a copy of a productive server, albeit less productive and simplified in terms of infrastructure and integration with the environment, but logically all components of the system should be present and the local loop should be as independent as possible from the activities of colleagues. Without this, there can be no productive work. Unfortunately, even the recommendations of MS do not give full freedom.
We gave each developer a dedicated developer circuit consisting of a separate machine with a server OS installed on it (yes, MS Dynamics CRM, installed only on the server OS), MS Dynamics CRM, MS SQL, Reporting Services and products necessary for development (MS VS, MS Dynamics CRM SDK, Git-client, MS SQL Management Studio, etc.) Ie we went a little further than the proposed MS option for allocating a separate organization for each developer, we allocated a separate copy of MS Dynamics CRM for each developer. And this is understandable, because In addition to customization, other components work alongside MS Dynamics CRM, which can also be changed by developers. As a result, sooner or later, it will lead to “elbowing” on one server, MS Dynamics CRM. As a bonus, we are able to provide a new developer with a prepared and pre-configured circuit for developing within an hour by cloning a virtual master machine.
Now everyone has everything for local development. You can edit the plug-in code, customize, create and delete objects in the database, assemble and install any components locally, debug exclusively. And, in the end, send your changes to the GIT branch (hereinafter referred to as GIT, because we use this version control system, but everything written is also true for any other SCM system). How do we version the changes? What is needed to build an automated build solution? We return to the list of the main parts of the system that change during the development process:
Plugins - no problem with them. C # code is there. The possibility of a commit in GIT, conflict resolution is. Building projects in a DLL is build C # code. Automating the installation of the assembled plug-in is also a solvable task is implemented through the MS Dynamics CRM API.
The directories decided to store as well as the code in GIT as comma separated files. It is convenient to edit using Excel, to disassemble the problem because while the format, in fact, remained textual. Made a mechanism for automated import and export of the contents of directories. The API of the system is flexible, it allows to automate any operations with entities. Of particular difficulty were related directories, multi-level directories. It was necessary to enter a separate attribute for each directory surrogate key for the purposes of synchronization and binding.
Web resources - on the one hand, must be present within Customization, since they are part of it, on the other - must be present explicitly in the GIT for debugging and versioning purposes. Web resources are versioned in a separate directory in GIT, and the same files must be imported into Customization before committing or preparing the package. At the current stage, this is an administrative decision that brings us occasionally surprises - the developer made changes to GIT, but forgot to import modified files into Customization or vice versa, which is worse. lost history of changes.
So far it works like this, but there is an assumption that you can add these files as links in Visual Studio csproj. Physically, they will be in unpacked customization. This will make it possible to avoid duplication and related problems.
Customization - the main source of headaches for the developer. To work with it in the MS Dynamics CRM SDK, a useful utility was discovered - SolutionPackager. It essentially unpacks the solution (Customization) file that we receive when exporting the solution from MS Dynamics CRM. If you look at the solution file, this is a giant xml file of undocumented format. At the output, after processing it with the SolutionPackager –th, we get the xml files spread out in the file structure, they are logically divided into entity types. The same tool can produce the inverse transform. Pack the unpacked solution into a single file. It is already possible to work with small xml files broken according to logic (even if not documented).
Versioning the solution in unpacked form also becomes a solvable problem. Plus, we get the opportunity to see in history who, what, when changed in relation to each element of customization and in what context it was done.
The process of making changes to customization during team development is as follows:
1) Pull out fresh “unpacked” Customization from GIT
2) We pack the received customization locally
3) Import it into local MS Dynamics CRM
4) We make edits to Customization in the local contour of the developer
5) We make changes to other components (if necessary), assemble them, install them locally
6) We debug changes. We turn to p.4 and p.5 by necessity repeatedly.
7) We export customization from a local server.
8) Extract the exported customization to a separate directory
9) Pull out the fresh “unpacked” Customization from GIT
10) Perform merge changes obtained in paragraph 8 with fresh customization. This is a very important step, because while we made our edits, someone could already commit the modified customization files. We should not grind these changes.
11) Committing changes.
The overhead of the process is great. We have tried to automate steps that do not require human intervention. This is p.2-3, p.7-9.
When working together on customization, the following scenarios are possible:
1. Developers make changes to different entities. After completing their tasks, everyone uploads the solution and commits the changes to the GIT. In this case, conflicts should not arise, since when unpacking the solution, the changes will appear in different xml files.
2. Developers make changes to one form of entity. After completing their tasks, each one unloads the solution from his organization, takes the latest version of the solution from the GIT and commits the changes to the GIT.
a. Developer A first completes the task, takes the latest version of the solution from GIT (in which there were no changes during the execution of the task), uploads its decision and commits its changes.
b. Developer B completes his task with the second one, takes the latest version of the solution from GIT (in which Developer A changes have appeared during this time), unloads his solution and encounters a conflict in the xml file of the form when committing changes.
Possible ways to resolve the conflict:
i. Developer B looks at the history of the form changes, which customizations were made by Developer A. If the changes are simple (for example, a field is added to the form), then Developer B repeats these changes in his organization, then reloads the solution from his organization and commits the changes on the form in overwrite mode.
ii. Developer B looks at the history of the form changes, which customizations were made by Developer A. If Developer A’s changes were multiple and difficult to repeat, Developer B re-imports the latest version of the solution from GIT into his organization, after which he performs the customizations needed to complete then reloads the solution from its organization and commits the changes on the form.
iii. Developer B looks at the history of the form changes which customizations were made by Developer A and regards them as minor / optional (for example, Developer A moved the form field within one section, and Developer B within its task rendered this field to another tab or recreated the field with a different system name, and deleted the old one from the form). In this case, Developer B commits its changes to the form in the overwrite mode.
iv. It is possible to merge / merge changes directly into the xml-code of the form (for example, if Developer A added his section to the form, and Developer B added his own), but this method is indicated by MS as unsupported. Also in this case, Developer B, after the merging of the xml-code, will have to check the importability of the entire solution into its organization. Only after that can he re-download the decision from his organization and commit the changes to the GIT.
For example, the most annoying case is the parallel addition to one form by different developers of Control of the same type. Developer A adds the “Modified” field to the “Meeting” form (see fig.)

Developer B adds the “Creation Date” field there at the same time (see fig.).

Developer A has time to commit his changes first.
Developer B, not forgetting to pull out the latest version of the file from GIT before committing his changes, sees that there were changes on the form. These changes will have to be manually done (see figure).
Ancillary database objects — versioning changes to the database structure is the subject of a separate large article. Ways to solve this problem depend on the input conditions. Within the same organization for different systems, teams, different DBMS, this task is solved in different ways. In the case of versioning changes to the MS Dynamics CRM database and auxiliary databases, we went along the path of using a separate Database project in MSVS with the subsequent generation of the .dacpac file. The Data-Tier Application Framework, by getting a .dacpac file with a description of the target database structure, is able to bring the database of any previous version to the target structure.
The main thing for us was that a versioning version was found with an automated casting of the database structure to the required state for any changes in the DDL, the clr code of the assemblies, the properties of the database, and the PreDeployment and PostDeployment scripts.In addition, the Database project allows you to synchronize with the working database in two modes:ď‚§ synchronized with the database: all objects from the database are transferred to the project. The update process is a complete synchronization, where the project is primary;Incremental. In the process of updating the database, only those objects that are present in the project are updated / modified, without affecting the rest. In the incremental approach, the primary database. In this case, there is no update of the project from the database.By selecting incremental synchronization, we left the control behind the MS Dynamics CRM objects behind the system, only objects that are explicitly modified in the Database project are added and changed (and every MS Dynamics CRM developer knows that the structure of the MS Dynamics CRM database should not be changed).Reports, as well as directories, are versioned in GIT. Automation of their installation in MSRS is quite simply implemented by Report Server Web Service Endpoints. An example of code that implements the loading of report templates is given below.
The complex of these approaches and mechanisms for automating operations allowed us to eventually implement Continuous Integration while developing a system not designed for this. That allowed to catch development errors at the stage of assembly and daily project deployment not only in C # code, but also in customization and all other components of MS Dynamics CRM.The final step in automating the development process was the birth of the installer, which installs all the system components (and there are significantly more of them than described above, because in addition to the components of MS Dynamics CRM, we also have supporting sites, services, services) on the expanded circuit. Full installation, including customization, changes in the database, reports, 4 sites, 2 services on average takes 1 hour (test loop). In this case, the lion's share of time is spent on importing customization in MS Dynamics CRM.Obviously, the full installation is not always required, therefore, initially laid the possibility of selective installation of components. This saves time when rolling updates., 2 : wizard . , Production Prod .


silent . .

. , TeamCity. UI TeamCity TeamCity , Deployment .
Here is a briefly obtained method of organizing teamwork for MS Dynamics CRM. Of course, something could be done differently, some tasks could be more effectively solved, somewhere in a completely different way to go. And now there are still unresolved issues - editing of web resources, difficulties of merge xml Customization source codes, unpredictable changes of xml files in the depths of MS Dynamics CRM and others. And, nevertheless, the existing approach works, allowing us to develop a large distributed development team, and the system is less and less distracted every day in solving organizational difficulties and “near-development” problems. The search for recommendations and ready-tested approaches to the organization of the development process for MS Dynamics CRM 2 years ago did not produce any noticeable results., - , , - .
,