We've open sourced a lightweight licensing framework we've been using internally over the last couple of years. In a 5 part series I'm covering the motivation behind building it, how you can use it, how you can extend it for your own scenarios and how you could use it in a real world situation:
- Part 1: Why build another licensing system?
- Part 2: Defining the desired behaviour
- Part 3: How to create and validate a license
- Part 4: How to implement custom validation logic
- Part 5: Real world usage patterns
In the last part I covered off how to create and validate a license, but we didn't delve into the extensibility points provided by
LicenseViolationException that allow us to implement custom validation logic. These extensibility points are enabled by
LicenseValidator which performs the validation by iterating over the collection of user definable rules, which implement the
ILicenseValidationRule interface and calls the
Validate() method, passing in the
LicenseCriteria extracted from the
Because we have not specified any hardcoded validation rules inside the ValidateMethod(), this allows us to easily create our own rules and pass them in to be evaluated. Endjin.Licensing only has a single built in validation rule –
LicenseHasNotExpiredRule, which simply checks to see if the license expiry date is less than the current date. Of course on a desktop application the user could modify the machine's system clock settings, so you'd need to implement a NTP based rule which would connect to an external time server to establish the correct, untampered with date.
In the example included in the Endjin.Licensing solution, we have an application that we want to license by number of processor cores. When creating the license in ServerApp, we need to specify a custom metadata entry to capture the number of processors the license supports:
To enforce this requirement, we need to implement a custom
ILicenseValidationRule which checks the number of cores allowed from the license metadata and validate it against the number of cores on the client's machine:
The diagram below shows the
ILicenseValidationRule inheritance hierarchy in the solution:
The second part of the extensibility mechanism is option to implement your own custom
LicenseViolationException. For simple implementations, your custom exception can contain a user friendly message explaining in what ways the license is invalid which you can display in your user interface.
The diagram below shows the
LicenseViolationException inheritance hierarchy in the solution:
Hopefully post has demonstrated how easy it is to implement custom validation rules in Endjin.Licensing. In the next post I'll be describing some real world usage scenarios of how you could use the Endjin.Licensing framework.