diff --git a/OpenRA.Game/ModData.cs b/OpenRA.Game/ModData.cs index d24dba8fda..98a19f3f88 100644 --- a/OpenRA.Game/ModData.cs +++ b/OpenRA.Game/ModData.cs @@ -217,6 +217,9 @@ namespace OpenRA MapCache.Dispose(); if (VoxelLoader != null) VoxelLoader.Dispose(); + + if (ObjectCreator != null) + ObjectCreator.Dispose(); } } diff --git a/OpenRA.Game/ObjectCreator.cs b/OpenRA.Game/ObjectCreator.cs index c9c3c0aa03..3d8f85e58c 100644 --- a/OpenRA.Game/ObjectCreator.cs +++ b/OpenRA.Game/ObjectCreator.cs @@ -18,7 +18,7 @@ using OpenRA.Primitives; namespace OpenRA { - public class ObjectCreator + public sealed class ObjectCreator : IDisposable { // .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 @@ -76,7 +76,6 @@ namespace OpenRA AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; assemblies = assemblyList.SelectMany(asm => asm.GetNamespaces().Select(ns => Pair.New(asm, ns))).ToArray(); - AppDomain.CurrentDomain.AssemblyResolve -= ResolveAssembly; } Assembly ResolveAssembly(object sender, ResolveEventArgs e) @@ -85,6 +84,9 @@ namespace OpenRA if (a.FullName == e.Name) return a; + if (assemblies == null) + return null; + return assemblies.Select(a => a.First).FirstOrDefault(a => a.FullName == e.Name); } @@ -159,6 +161,23 @@ namespace OpenRA .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)] public sealed class UseCtorAttribute : Attribute { } }