Files
ShrinkContext.AppAdapter/Runtime/ShrinkAppInstallerComponent.cs
T
cneicy 2e8cc588c4
Publish UPM package / publish (push) Failing after 1s
chore: initialize standalone UPM package
2026-08-26 02:49:53 +08:00

63 lines
2.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
using ShrinkApp;
namespace ShrinkContext.AppAdapter
{
/// <summary>
/// 把现有 <see cref="IShrinkAppModuleInstaller"/> 包装为 ShrinkContext 组件:
/// - inject 由 <c>DependsOn</c> 派生(模块依赖 → 模块键),依赖未就绪时安装器保持非活动等待,
/// 而不是像拓扑排序那样直接抛错;
/// - provide 发布模块键 <c>app.module.&lt;ModuleId&gt;</c>(安装器 Active 后对依赖者可见);
/// - apply 依次执行 RegisterServices + InitializeAsyncconfig 必须传入 <see cref="ShrinkAppServices"/>。
///
/// 兼容安装器只负责执行既有 RegisterServices + InitializeAsync。需要停用时撤回服务的模块应使用
/// 原生 Context 组件,并通过 ShrinkAppServices.TryUnregister(instance) 登记对应逆操作。
/// </summary>
public sealed class ShrinkAppInstallerComponent : IShrinkComponent
{
/// <summary>模块键前缀:依赖声明 <c>DependsOn = ["a"]</c> 映射为 <c>app.module.a</c>。</summary>
public const string ModuleKeyPrefix = "app.module.";
private readonly IShrinkAppModuleInstaller _installer;
private readonly ShrinkAppSettings? _settings;
private readonly string[] _inject;
public ShrinkAppInstallerComponent(IShrinkAppModuleInstaller installer, ShrinkAppSettings? settings = null)
{
_installer = installer ?? throw new ArgumentNullException(nameof(installer));
_settings = settings;
_inject = (installer.DependsOn ?? Array.Empty<string>())
.Where(id => !string.IsNullOrWhiteSpace(id))
.Select(id => ModuleKeyPrefix + id.Trim())
.ToArray();
}
public string Name => "app-installer:" + _installer.ModuleId;
public IReadOnlyList<string> Inject => _inject;
public IReadOnlyList<string> Provide => new[] { ModuleKeyPrefix + _installer.ModuleId };
public IShrinkAppModuleInstaller Installer => _installer;
public async UniTask ApplyAsync(ShrinkCtx ctx, object? config)
{
if (config is not ShrinkAppServices services)
throw new InvalidOperationException(
$"ShrinkAppInstallerComponent '{_installer.ModuleId}' requires ShrinkAppServices as fiber config.");
// 先发布模块键再执行安装:装载期绑定对依赖者不可见(提供者须 Active),
// 供给冲突(重复 ModuleId)在安装器初始化之前即失败
ctx.Set(Provide[0], _installer.ModuleId);
var appContext = ShrinkAppContext.CreateStandalone(services, _settings);
_installer.RegisterServices(appContext);
await _installer.InitializeAsync(appContext);
}
}
}