From 8dd50c0421c011170c0132eec6361d5e3d5ecfee Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Mon, 24 Apr 2017 22:26:47 +0000 Subject: [PATCH] Keep ObjectCreator ResolveAssembly override bound until disposal. --- OpenRA.Game/ModData.cs | 3 +++ OpenRA.Game/ObjectCreator.cs | 23 +++++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) 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 { } }