Context
My projects are separated into one assembly with Interfaces, which I call the Core
, and another assembly with the implementation, which I call the Implementation
. In reality, the namespaces look like this:
CompanyName.ProjectName.Core
CompanyName.ProjectName
The first project has zero business logic in it (May or may not have "domain" logic, logic related to the basic instantiation and validation of models). The second project has all of the business logic in it (May or may not have "domain" logic, as I define it here).
Any other projects in any other systems which wish to consume this domain would implement only the Core
and nothing else. From there, it can define usage of the interfaces and models defined within.
Any other Startup
Projects would have to also consume SOME version of Implementation, in order to perform Dependency-Injection on their classes which are consuming the Core
. It is likely that they will be consuming the Implementation project I defined above... especially if it is the only implementation of its related Core
.
The Problem
In general I don't distribute my implementation unless it is paid for. This allows users to freely review, navigate, and implement a Core of my product, without the actual proprietary implementation unless they buy it.
In this one case, I have created some Abstract
Base Classes which contain a lot of boiler plate implementation of the Core
Interfaces
. For all intents and purposes, this assembly with the Base Classes is the Implementation project, which I do not want unauthorized users to have access to.
However, I need them to have access to the definitions of the Abstract Classes so they can implement them. So technically, they are Core
Material. Contracts, if you will.
My Failed Solution 1
Idea 1 is to define the Abstract Class in the Core project, but make all of the Virtual methods throw not implemented exceptions.
If I create the class: CompanyName.ProjectName.Core.BaseClass()
, then the consumer will implement that class. Then when I later consume their libraries, my Actual CompanyName.ProjectName.BaseClass()
wouldn't be recognized as the same object.
If I create the class: CompanyName.ProjectName.BaseClass()
inside my Core
assembly, then when I later consume their libraries, my Actual implementation will throw an exception that there are two instances of CompanyName.ProjectName.BaseClass()
, and it doesn't know which one to use.
My Failed Solution 2
Idea 2 is to go ahead and give them the same exact implementation library... but before giving it to them, remove all of the logic and throw not implemented exceptions.
This works, but it is a lot of work for me, and I have to give the libraries to them manually. So they won't be able to use NuGet or something to pull them.
My Failed Solution 3
Similar to Idea 2; Idea 3 is to create a new NuGet package named CompanyName.ProjectName.________
which is the same as Idea 2 above.
I haven't tried this yet, but I assume it would work. They would implement the library, and when they give me their assemblies, I would just replace their bogus dll with the one I have. Or, in reverse, when they pay for the product, they would just replace their bogus one with the paid one.
One problem here is... I haven't tested this directly, so I'm unsure if it would work. Though, given my knowledge of namespaces and assembly signing, I assume it would be easy to make it work. I can't test it without an acceptable naming convention though, so...
The main problem here is, what would that NuGet package be called? It can't be Core, Implementation, or Empty. Is there already a pattern for this, or do I need to make something up.
My Failed Solution 4
Purchase an obfuscator and implement a licensing scheme such that... un-licensed users would be blocked from accessing the implementation, but could still consume the contracts.
This is expensive and requires the work to implement the licensing scheme... I actually plan to do all of this, but not until the new year. I am hoping there is some other answer that is good to use in the intermediary.