Load all assemblies from the MSBuild folder if not already loaded#107
Conversation
Changes the check for previously loaded assemblies to only fail if we already registered them via MSBuildLocator. Then adds previously loaded assemblies to the list of loaded assemblies so they aren't loaded again.
Don't throw an error if the assembly is already loaded.
| // If the assembly was already loaded, return that. This could theoretically cause version problems, but the user shouldn't be | ||
| // trying to load an MSBuild that is incompatible with the version of the assembly they currently have loaded. | ||
| Assembly loadedAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.GetName().Name.Equals(assemblyName.Name)); | ||
| if (loadedAssembly != null) | ||
| { | ||
| // Automatically unregister the handler once all supported assemblies have been loaded. | ||
| if (Interlocked.Increment(ref numResolvedAssemblies) == s_msBuildAssemblies.Length) | ||
| { | ||
| Unregister(); | ||
| } | ||
|
|
||
| assembly = Assembly.LoadFrom(targetAssembly); | ||
| loadedAssemblies.Add(assemblyName.FullName, assembly); | ||
| return assembly; | ||
| loadedAssemblies.Add(assemblyName.FullName, loadedAssembly); | ||
| return loadedAssembly; | ||
| } | ||
|
|
21c5c76 to
0c47d1e
Compare
| <PropertyGroup> | ||
| <OutputType>Exe</OutputType> | ||
| <TargetFrameworks>net471;netcoreapp2.1</TargetFrameworks> | ||
| <TargetFrameworks>net471;netcoreapp3.1</TargetFrameworks> |
| @@ -37,7 +35,7 @@ public static class MSBuildLocator | |||
| #endif | |||
|
|
|||
| // Used to determine when it's time to unregister the registeredHandler. | |||
| var error = $"{typeof(MSBuildLocator)}.{nameof(Unregister)} was called, but no MSBuild instance is registered." + Environment.NewLine; | ||
| if (numResolvedAssemblies == 0) | ||
| if (!registerCalled) | ||
| { | ||
| error += $"Ensure that {nameof(RegisterInstance)}, {nameof(RegisterMSBuildPath)}, or {nameof(RegisterDefaults)} is called before calling this method."; |
There was a problem hiding this comment.
I think this whole error system might be kinda useless now--we no longer really have the concept of Unregister since the assemblies we might resolve is now unbounded. This change is OK but I think it's worth thinking of just rewriting this whole thing to do nothing.
| public static bool CanRegister => !IsRegistered && !LoadedMsBuildAssemblies.Any(); | ||
|
|
||
| private static IEnumerable<Assembly> LoadedMsBuildAssemblies => AppDomain.CurrentDomain.GetAssemblies().Where(IsMSBuildAssembly); | ||
| public static bool CanRegister => !IsRegistered && !loadedAssemblies.Any(); |
There was a problem hiding this comment.
Naturally looking at the diff that's the result of the change I asked you to make revealed to me that I was wrong and this isn't what we want. I'll push a fix.
This is important in ways I didn't think of when I suggested removing it. We still want the guardrail of "you have MSBuild next to your application/already loaded MSBuild assemblies before you called Register".
| { | ||
| var error = $"{typeof(MSBuildLocator)}.{nameof(Unregister)} was called, but no MSBuild instance is registered." + Environment.NewLine; | ||
| if (numResolvedAssemblies == 0) | ||
| if (!registerCalled) |
There was a problem hiding this comment.
This error message is now wrong. Unregister isn't called automatically, so the only way IsRegistered would be false but registerCalled would be true is if they manually Unregistered twice, which probably isn't a big thing. I'd prefer to unset registerCalled here and keep just the one message.
There was a problem hiding this comment.
I'm not 100% sure I understand what you mean but go ahead and do that.
|
|
||
| // Used to determine when it's time to unregister the registeredHandler. | ||
| private static int numResolvedAssemblies; | ||
| private static bool registerCalled = false; |
There was a problem hiding this comment.
Stale comment—we don't unregister the registeredHandler.
Changes the check for previously loaded assemblies to only fail if we already registered them via MSBuildLocator. Then adds previously loaded assemblies to the list of loaded assemblies so they aren't loaded again.
This may cause version mismatch issues, but if you had previously loaded some but not all of our assemblies, I'd say that's something for you to figure out. 😄
Fixes #103.
Also Fixes #38.