nunit-console
nunit-console copied to clipboard
Simplify or remove loading of engine by reflection via TestEngineActivator
Having just lost yet another day to weird reflection issues, I'd like to have a look at whether we can remove this structure for v4.0, inline with our "Improved Developer Experience" objective.
If I understand the history correctly, the reason this was implemented in v3 was with the expectation that users would install a single centralised engine, and have runners discover and make use of that. We've found instead that runners have chosen to each distribute their own local copy of the engine, meaning this has become a source of extra complication in the engine which isn't well used.
Having made a start on #885, I'm now looking at the below structure for the API assemblies:
nunit.engine.extensions.api.dll ExtensionAttributes ITestPackage
nunit.extension.project-loader.api.dll (And 4 other similar assemblies) API for individual extensions. Broken into individual assemblies to allow us to make any necessary breaking changes in a less disruptive manner.
nunit.engine.api.dll API's for runners to interact with the engine.
Once I'd got that far, I'm now thinking that nunit.engine.api.dll doesn't serve much purpose except to expose the public types from nunit.engine.dll.
How about we merge what's left of nunit.engine.api.dll into the nunit.engine assembly, and simply expose only the API types that we want people to use. (As we planned in #886 anyway). This would also mean that TestEngineActivator could simply create a TestEngine via the constructor, and we'd remove a good amount of the reflection complexity, impeded debugging ability and type loading complications we currently face.
What do people think? 🙂
Having an API assembly does a few things...
- You can modify the implementation under that API.
- You can allow other people to replace all or part of the engine, provided the API is respected.
- You can decouple API versioning from engine versioning.
- You can do drop-in replacement of the engine without rebuilding the runner that is using it.
There's no doubt that all of the above are potentially useful. The question is how useful and at what cost.