Keep ObjectCreator ResolveAssembly override bound until disposal.

This commit is contained in:
Paul Chote
2017-04-24 22:26:47 +00:00
parent 99f3f37afe
commit 8dd50c0421
2 changed files with 24 additions and 2 deletions

View File

@@ -217,6 +217,9 @@ namespace OpenRA
MapCache.Dispose(); MapCache.Dispose();
if (VoxelLoader != null) if (VoxelLoader != null)
VoxelLoader.Dispose(); VoxelLoader.Dispose();
if (ObjectCreator != null)
ObjectCreator.Dispose();
} }
} }

View File

@@ -18,7 +18,7 @@ using OpenRA.Primitives;
namespace OpenRA namespace OpenRA
{ {
public class ObjectCreator public sealed class ObjectCreator : IDisposable
{ {
// .NET does not support unloading assemblies, so mod libraries will leak across mod changes. // .NET does not support unloading assemblies, so mod libraries will leak across mod changes.
// This tracks the assemblies that have been loaded since game start so that we don't load multiple copies // This tracks the assemblies that have been loaded since game start so that we don't load multiple copies
@@ -76,7 +76,6 @@ namespace OpenRA
AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly;
assemblies = assemblyList.SelectMany(asm => asm.GetNamespaces().Select(ns => Pair.New(asm, ns))).ToArray(); assemblies = assemblyList.SelectMany(asm => asm.GetNamespaces().Select(ns => Pair.New(asm, ns))).ToArray();
AppDomain.CurrentDomain.AssemblyResolve -= ResolveAssembly;
} }
Assembly ResolveAssembly(object sender, ResolveEventArgs e) Assembly ResolveAssembly(object sender, ResolveEventArgs e)
@@ -85,6 +84,9 @@ namespace OpenRA
if (a.FullName == e.Name) if (a.FullName == e.Name)
return a; return a;
if (assemblies == null)
return null;
return assemblies.Select(a => a.First).FirstOrDefault(a => a.FullName == e.Name); return assemblies.Select(a => a.First).FirstOrDefault(a => a.FullName == e.Name);
} }
@@ -159,6 +161,23 @@ namespace OpenRA
.SelectMany(ma => ma.GetTypes()); .SelectMany(ma => ma.GetTypes());
} }
~ObjectCreator()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
void Dispose(bool disposing)
{
if (disposing)
AppDomain.CurrentDomain.AssemblyResolve -= ResolveAssembly;
}
[AttributeUsage(AttributeTargets.Constructor)] [AttributeUsage(AttributeTargets.Constructor)]
public sealed class UseCtorAttribute : Attribute { } public sealed class UseCtorAttribute : Attribute { }
} }