Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load all assemblies from the MSBuild folder if not already loaded #107

Merged
merged 7 commits into from
Dec 22, 2020

Conversation

Forgind
Copy link
Member

@Forgind Forgind commented Dec 8, 2020

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.

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.
Comment on lines 209 to 217
// 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;
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete

@Forgind Forgind changed the title Do not error if some assemblies were already loaded Fixes #103 Do not error if some assemblies were already loaded and load all assemblies from the MSBuild folder Fixes #103 Dec 18, 2020
@Forgind Forgind changed the title Do not error if some assemblies were already loaded and load all assemblies from the MSBuild folder Fixes #103 Do not error if some assemblies were already loaded and load all assemblies from the MSBuild folder Dec 18, 2020
@Forgind Forgind changed the title Do not error if some assemblies were already loaded and load all assemblies from the MSBuild folder Load all assemblies from the MSBuild folder if not already loaded Dec 18, 2020
@rainersigwald rainersigwald added this to the December 2020 milestone Dec 18, 2020
@Forgind Forgind mentioned this pull request Dec 18, 2020
@Forgind Forgind force-pushed the permit-already-loaded-assemblies branch from 21c5c76 to 0c47d1e Compare December 18, 2020 20:43
@@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net471;netcoreapp2.1</TargetFrameworks>
<TargetFrameworks>net471;netcoreapp3.1</TargetFrameworks>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed?

@@ -37,7 +35,7 @@ public static class MSBuildLocator
#endif

// Used to determine when it's time to unregister the registeredHandler.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

src/MSBuildLocator/MSBuildLocator.cs Show resolved Hide resolved
src/MSBuildLocator/MSBuildLocator.cs Show resolved Hide resolved
Comment on lines 230 to 233
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.";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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".
@@ -239,7 +230,7 @@ public static void Unregister()
if (!IsRegistered)
{
var error = $"{typeof(MSBuildLocator)}.{nameof(Unregister)} was called, but no MSBuild instance is registered." + Environment.NewLine;
if (numResolvedAssemblies == 0)
if (!registerCalled)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% sure I understand what you mean but go ahead and do that.

@@ -37,7 +35,7 @@ public static class MSBuildLocator
#endif

// Used to determine when it's time to unregister the registeredHandler.
private static int numResolvedAssemblies;
private static bool registerCalled = false;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment—we don't unregister the registeredHandler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants