summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI/Framework/ModLoading/AssemblyLoader.cs')
-rw-r--r--src/SMAPI/Framework/ModLoading/AssemblyLoader.cs37
1 files changed, 25 insertions, 12 deletions
diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
index 2fb2aba7..d41774a9 100644
--- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
+++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs
@@ -12,7 +12,7 @@ using StardewModdingAPI.Metadata;
namespace StardewModdingAPI.Framework.ModLoading
{
/// <summary>Preprocesses and loads mod assemblies.</summary>
- internal class AssemblyLoader
+ internal class AssemblyLoader : IDisposable
{
/*********
** Properties
@@ -20,9 +20,6 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <summary>Encapsulates monitoring and logging.</summary>
private readonly IMonitor Monitor;
- /// <summary>Whether to enable developer mode logging.</summary>
- private readonly bool IsDeveloperMode;
-
/// <summary>Metadata for mapping assemblies to the current platform.</summary>
private readonly PlatformAssemblyMap AssemblyMap;
@@ -32,6 +29,9 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <summary>A minimal assembly definition resolver which resolves references to known loaded assemblies.</summary>
private readonly AssemblyDefinitionResolver AssemblyDefinitionResolver;
+ /// <summary>The objects to dispose as part of this instance.</summary>
+ private readonly HashSet<IDisposable> Disposables = new HashSet<IDisposable>();
+
/*********
** Public methods
@@ -39,13 +39,11 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <summary>Construct an instance.</summary>
/// <param name="targetPlatform">The current game platform.</param>
/// <param name="monitor">Encapsulates monitoring and logging.</param>
- /// <param name="isDeveloperMode">Whether to enable developer mode logging.</param>
- public AssemblyLoader(Platform targetPlatform, IMonitor monitor, bool isDeveloperMode)
+ public AssemblyLoader(Platform targetPlatform, IMonitor monitor)
{
this.Monitor = monitor;
- this.IsDeveloperMode = isDeveloperMode;
- this.AssemblyMap = Constants.GetAssemblyMap(targetPlatform);
- this.AssemblyDefinitionResolver = new AssemblyDefinitionResolver();
+ this.AssemblyMap = this.TrackForDisposal(Constants.GetAssemblyMap(targetPlatform));
+ this.AssemblyDefinitionResolver = this.TrackForDisposal(new AssemblyDefinitionResolver());
// generate type => assembly lookup for types which should be rewritten
this.TypeAssemblies = new Dictionary<string, Assembly>();
@@ -144,10 +142,26 @@ namespace StardewModdingAPI.Framework.ModLoading
.FirstOrDefault(p => p.GetName().Name == shortName);
}
+ /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
+ public void Dispose()
+ {
+ foreach (IDisposable instance in this.Disposables)
+ instance.Dispose();
+ }
+
/*********
** Private methods
*********/
+ /// <summary>Track an object for disposal as part of the assembly loader.</summary>
+ /// <typeparam name="T">The instance type.</typeparam>
+ /// <param name="instance">The disposable instance.</param>
+ private T TrackForDisposal<T>(T instance) where T : IDisposable
+ {
+ this.Disposables.Add(instance);
+ return instance;
+ }
+
/****
** Assembly parsing
****/
@@ -166,9 +180,8 @@ namespace StardewModdingAPI.Framework.ModLoading
// read assembly
byte[] assemblyBytes = File.ReadAllBytes(file.FullName);
- AssemblyDefinition assembly;
- using (Stream readStream = new MemoryStream(assemblyBytes))
- assembly = AssemblyDefinition.ReadAssembly(readStream, new ReaderParameters(ReadingMode.Deferred) { AssemblyResolver = assemblyResolver });
+ Stream readStream = this.TrackForDisposal(new MemoryStream(assemblyBytes));
+ AssemblyDefinition assembly = this.TrackForDisposal(AssemblyDefinition.ReadAssembly(readStream, new ReaderParameters(ReadingMode.Immediate) { AssemblyResolver = assemblyResolver, InMemory = true }));
// skip if already visited
if (visitedAssemblyNames.Contains(assembly.Name.Name))