microsoft / MSBuildLocator

An API to locate MSBuild assemblies from an installed Visual Studio location. Use this to ensure that calling the MSBuild API will use the same toolset that a build from Visual Studio or msbuild.exe would.
Other
218 stars 83 forks source link

Roslyn Analyzer #67

Open rainersigwald opened 5 years ago

rainersigwald commented 5 years ago

There's a very common problem using Locator, which is that the natural code change to use it:

 void DoStuff()
 {
+    MSBuildLocator.RegisterDefaults();
     var project = new Microsoft.Build.Evaluation.Project(projectPath);

Doesn't work, because .NET loads all types referenced in a method before executing that method, so it tries to load MSBuild APIs before the Locator has made that possible.

64 is one example of this but there have been a ton.

We can't fix this in the deployed code, because it won't have been loaded in time to do anything.

It might be possible, though, to create a Roslyn analyzer that ships as part of this package that checks to make sure there are no MSBuild APIs in a method that calls the locator. That would make things much easier for new users.

cdmihai commented 3 years ago

Why not do it in a static constructor from a type that does not reference any other type? Excluding the usual caveats with exceptions from type constructors.

class LoadMSBuild
{
   static LoadMSbuild(){ MSBuildLocator.RegisterDefaults(); }
}