-
Notifications
You must be signed in to change notification settings - Fork 83
Description
Problem
If any of this logic is flawed, I'd be happy to discuss. I'm putting my analysis of the current situation below, but I'm aware that there may be other approaches or alternatives to solve this particular problem in a more elegant way.
When using coyote version .NET 8 on .NET 6 projects, the IL rewriting produces tests that don't execute in mstest (they show as aborted). I have seen other issues in the issue list where people noticed this behavior as well. The solution seems to be to pin the .net version of the coyote CLI to the target framework version specified in your project.
Our team has a large monorepo that currently targets .NET 6. We are migrating to .NET 8 slowly, but it is a long process based on the number of projects we have. This means I can't use coyote as a local tool for the .NET 6 projects because it appears to only target .NET 8 and IL rewriting across framework targets causes compatibility issues. I think this is a non-issue if you are using Mono.Cecil target framework version that matches your project target framework version because it is a library that doesn't require you to be pinned to a specific version of .NET.
Currently .net local tools only support a single target framework. Global tools support multiple target frameworks but require an out of band dotnet tool install --global --framework <framework> <toolname> command in order to install the CLI. This means that you can't run dotnet tool restore in the repo that targets a specific framework version because dotnet tool restore also doesn't support target frameworks. It uses --local mode and local mode throws errors when you specify dotnet tool install --local --framework "net6.0". The install command updates the manifest and allows you to run dotnet tool restore. The manifest doesn't exist for global tools, which is the core problem. No easy way to add in dependencies for all the developers who work on the repo.
Nuget supports multiple target frameworks and running a dotnet restore will download the framework targets for the specific package your project references. That way, the multiple target frameworks of Mono.Cecil would be mapped to the target framework of the project.
Proposal
It should be possible to expose coyote cli functionality as a library by changing some of the internal functions and classes to public. This would allow integration with msbuild. The ability to use RoslynCodeTaskFactory would avoid compatibility issues with specific msbuild versions because no hard dependency on a msbuild dll would be taken. Only msbuild properties files would be exposed.
There is a proposal #403 to expose a msbuild target as a library #403. Going through this approach ultimately leads to a huge issue with compatibility in visual studio. Visual Studio uses the .NET Framework of msbuild and that causes runtime errors when trying to build projects that target a custom msbuild task. For more context, you can look at the setup done by the slngen project here https://github.com/microsoft/slngen/blob/main/src%2FMicrosoft.VisualStudio.SlnGen%2FMicrosoft.VisualStudio.SlnGen.targets
The CLI project has multiple entry points that provide the only exposed surface to these capabilities:
The approach above would involve exposing the API surface utilized by these commands as public in the coyote libraries so that they could be called from an outside source.
An alternative approach would be to create some kind of generic public layer that doesn't expose the internals of the coyote libraries but allows someone to use coyote cli capabilities as a library. This would be similar to a business logic layer or local application service in a traditional 3 tier app architecture. The CLI would interface with this layer and push most of its "business logic" down so that a different caller could get similar functionality to what the CLI provides (validation, command logic etc) without duplicating all the code in the CLI.