It’s pretty common for developers to create custom tools for their work. These can range from automation, to helper libraries to full-fledged applications helping with (or streamlining) certain tasks. After all, reinventing the wheel for every project is a colossal waste of time. Thus, it wasn’t really any kind of surprise when, working with other companies building business applications for Microsoft products, I found different types of in-house SDKs filled with various helper classes. Unfortunately, all those SDKs, while helpful, were never applied across the board to all the projects a given company was working on; in some cases, these tools were applied inconsistently even in one project.
So, we decided to do better.
Of course, initially our set of in-house SDKs started off very similar – a few helper classes and tools manually copied from project to project, but a philosophy was born. What if we could use these tools across the board, on ALL projects, regardless if we’re working on an Microsoft Dynamics project, an Microsoft SharePoint project… or a custom ASP site?
Loosely coupled layer
Our tools aren’t just a set of helper classes that “do helpful stuff” when you invoke them; they are a new layer that we work with. This layer ties up our model classes, data repositories and business logic with the underlying data layer and (where applicable) hooks up to an existing system (for example, as Microsoft Dynamics 365 Plugins).
This is done using the “loose coupling” paradigm with some clever base classes thrown into the mix. Each logic class implements its own interface, uses repository interfaces for data access, and those repositories return our data models. Once the core structures for a project are created, a coder might not even care if they are creating logic for Microsoft Dynamics 365, Microsoft SharePoint or something else.
The repositories themselves are based on a set of powerful base classes for the most common data sources we work with, be it CRM entities, SharePoint lists or custom SQL data sets (accessed via Entity Framework).
Testing all angles
With the loosely coupled layers it’s easy to test our logic – without even starting up the UI. Pure unit tests are great if logic permits them, but often there’s at least some component of an existing system that plays a crucial role in the logic. Testing a method which calculates an average based on a few values provided is easy… testing a method which calculates system-averages when a new record is added? Not so much.
To facilitate testing we can utilize a few nifty little helper classes from our Projects library like “read only” data repositories which allow testing using actual data (from a CRM, for example) and save changes in-memory only. This allows us to test our system-dependant logic without connecting to the underlying system or making permanent changes.
Business data driven development
Normally, event-driven development means implementing and using events inside your code. However, we’re talking about something different – we want to focus on events related to handling of business data. A user adds a new record to the system – how should the system respond? With our Projects layer, we can quickly develop and deploy business logic handling just such cases.
We’ve based this loosely on the event execution pipeline from Microsoft Dynamics 365, where each operation (where applicable) has several stages – validation, pre-operation and post-operation. While CRM projects map these stages almost 1-to-1 with our own code for basic CRUD operations, our repositories allow us to implement such handling for any project we’re working on.
Going deeper with metadata repositories
Our next stage of development is creating repositories for metadata and integrating them with our base Projects code. The idea here is to have default CRUD functionality based on metadata information, rather than relying on repositories created by developers. Those can and will still exist, of course, and any more advanced logic code will likely still require these traditional repositories. But with metadata implementation we can create basic forms and features much faster, as these can now be automated.
Our Projects SDK makes use of custom attributes, allowing us to mark logic interfaces with additional metadata. This additional information is used to automate deployment procedures. While this is still an ongoing process, we already have a custom tool which fully automates deployment of Microsoft Dynamics 365 plugins created using our Projects SDKs – the result is faster deployment and fewer human errors.
While the underlying principle of such tools is to speed up and simplify deployment, it’s important to have the flexibility of having custom or otherwise non-standard deployment steps. As such, our deployment tool for Microsoft Dynamics 365 also supports the configuration of other, user-defined, steps and stages.