feat(mod): 完成外部 DLL 事务热替换
This commit is contained in:
+49
-1
@@ -17,6 +17,14 @@ namespace ShrinkModFramework
|
||||
public Assembly Assembly;
|
||||
}
|
||||
|
||||
internal sealed class RevisionState
|
||||
{
|
||||
public Dictionary<string, ExternalAssemblyRevision> Current =
|
||||
new(StringComparer.OrdinalIgnoreCase);
|
||||
public Dictionary<string, string> Known =
|
||||
new(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private static readonly Dictionary<string, ExternalAssemblyRevision> CurrentAssemblyRevisions =
|
||||
new(StringComparer.OrdinalIgnoreCase);
|
||||
private static readonly HashSet<Assembly> ExternalAssemblyHistory = new();
|
||||
@@ -101,6 +109,12 @@ namespace ShrinkModFramework
|
||||
.ToArray())
|
||||
{
|
||||
CurrentAssemblyRevisions.Remove(missingPath);
|
||||
var assemblyName = Path.GetFileNameWithoutExtension(missingPath);
|
||||
if (KnownAssemblyFiles.TryGetValue(assemblyName, out var knownPath) &&
|
||||
string.Equals(knownPath, missingPath, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
KnownAssemblyFiles.Remove(assemblyName);
|
||||
}
|
||||
}
|
||||
|
||||
return CurrentAssemblyRevisions.Values
|
||||
@@ -112,6 +126,35 @@ namespace ShrinkModFramework
|
||||
internal static bool IsExternalAssembly(Assembly assembly) =>
|
||||
assembly != null && ExternalAssemblyHistory.Contains(assembly);
|
||||
|
||||
internal static RevisionState CaptureState()
|
||||
{
|
||||
return new RevisionState
|
||||
{
|
||||
Current = CurrentAssemblyRevisions.ToDictionary(
|
||||
pair => pair.Key,
|
||||
pair => pair.Value,
|
||||
StringComparer.OrdinalIgnoreCase),
|
||||
Known = KnownAssemblyFiles.ToDictionary(
|
||||
pair => pair.Key,
|
||||
pair => pair.Value,
|
||||
StringComparer.OrdinalIgnoreCase)
|
||||
};
|
||||
}
|
||||
|
||||
internal static void RestoreState(RevisionState state)
|
||||
{
|
||||
if (state == null)
|
||||
throw new ArgumentNullException(nameof(state));
|
||||
|
||||
CurrentAssemblyRevisions.Clear();
|
||||
foreach (var pair in state.Current)
|
||||
CurrentAssemblyRevisions[pair.Key] = pair.Value;
|
||||
|
||||
KnownAssemblyFiles.Clear();
|
||||
foreach (var pair in state.Known)
|
||||
KnownAssemblyFiles[pair.Key] = pair.Value;
|
||||
}
|
||||
|
||||
internal static bool TryGetCurrentRevision(Assembly assembly, out string revision)
|
||||
{
|
||||
foreach (var current in CurrentAssemblyRevisions.Values)
|
||||
@@ -138,7 +181,6 @@ namespace ShrinkModFramework
|
||||
internal static void ResetForTesting()
|
||||
{
|
||||
CurrentAssemblyRevisions.Clear();
|
||||
ExternalAssemblyHistory.Clear();
|
||||
KnownAssemblyFiles.Clear();
|
||||
if (_resolveRegistered)
|
||||
{
|
||||
@@ -147,6 +189,12 @@ namespace ShrinkModFramework
|
||||
}
|
||||
}
|
||||
|
||||
internal static void ResetForDomainReload()
|
||||
{
|
||||
ResetForTesting();
|
||||
ExternalAssemblyHistory.Clear();
|
||||
}
|
||||
|
||||
private static string ComputeSha256(byte[] bytes)
|
||||
{
|
||||
using var sha256 = SHA256.Create();
|
||||
|
||||
Reference in New Issue
Block a user