feat: 公开宿主组合加载 API、Forge 风格依赖版本区间与加载顺序、程序集解析策略
Publish UPM package / publish (push) Successful in 3s
Publish NuGet packages / publish (push) Successful in 2m18s

- ShrinkModComponentDiscovery.Discover 公开:只发现、不执行生命周期
- ShrinkModLoader.LoadComposed / ShrinkModCordisRuntime.ApplyComposedAsync:宿主提供元数据组合加载,支持纯数据包与 IShrinkModWrapper 公开真实实例
- 公开 TryAttachEventBusInstance,随生命周期逆操作释放
- 依赖新增 VersionRange(Maven/Forge 区间语法)与 Ordering(Before/After)
- AssemblyResolvePolicy 可限制跨模组程序集解析
This commit is contained in:
cneicy committed 2026-11-10 07:39:22 +08:00
1 parent 5398036d3b
commit d15bf00512
29 files changed
+917 -132

No files matched your search

+38 -2
View File
@@ -37,9 +37,9 @@ namespace ShrinkModFramework
try
{
var authorizedPaths = authorizedDllPaths?.ToArray() ?? Array.Empty<string>();
var sources = ShrinkModComponentDiscovery.Discover(
var sources = ShrinkModComponentDiscovery.DiscoverCurrent(
settings, verboseLogging, authorizedPaths);
await _host.ApplyAsync(sources);
await _host.ApplyAsync(sources, () => ShrinkExternalModAssemblyLoader.RestoreState(revisionState));
}
catch
{
@@ -54,6 +54,42 @@ namespace ShrinkModFramework
return _host.Mods;
}
/// <summary>提交宿主组合;生命周期或发现失败时恢复之前的程序集 revision 和组件。</summary>
public static async UniTask<IReadOnlyDictionary<string, ShrinkModHandle>> ApplyComposedAsync(
ShrinkModFrameworkSettings settings, IReadOnlyList<ShrinkModComponentSource> sources)
{
if (sources == null) throw new ArgumentNullException(nameof(sources));
settings ??= ShrinkModFrameworkSettings.Instance;
var verbose = settings != null && settings.verboseLogging;
if (_host == null) _host = new ShrinkModContextHost(settings == null || settings.enableHarmonyPatching, verbose);
var previous = ShrinkExternalModAssemblyLoader.CaptureState();
try
{
var states = sources.Where(source => source != null && source.DiscoveryState != null)
.Select(source => source.DiscoveryState).Distinct().ToArray();
var composedState = new ShrinkExternalModAssemblyLoader.RevisionState();
foreach (var state in states)
{
foreach (var pair in state.Current)
{
if (composedState.Current.TryGetValue(pair.Key, out var other) && other.Revision != pair.Value.Revision)
throw new InvalidOperationException($"Conflicting discovered revisions for {pair.Key}.");
composedState.Current[pair.Key] = pair.Value;
}
foreach (var pair in state.Known) composedState.Known[pair.Key] = pair.Value;
}
ShrinkExternalModAssemblyLoader.RestoreState(composedState);
ShrinkModNetworkManager.Configure(settings == null || settings.enableNetworkSync, verbose);
await _host.ApplyAsync(sources, () => ShrinkExternalModAssemblyLoader.RestoreState(previous));
}
catch
{
ShrinkExternalModAssemblyLoader.RestoreState(previous);
throw;
}
return _host.Mods;
}
public static IReadOnlyShrinkModRegistry<T> GetOrCreateRegistry<T>(string name) =>
Host.GetOrCreateRegistry<T>(name);