在Nuke中实现Targets间状态共享:是否有内置或更简洁方案?
Nuke Targets 之间共享状态的内置解决方案
你可以使用Nuke内置的Context对象来跨Target共享状态,这是官方推荐的简洁实现方式,无需额外定义类字段或属性,也能保持代码的整洁性。
1. 使用Context存储和读取状态
Context是NukeBuild基类提供的上下文存储容器,支持通过键值对存储任意类型的数据,并且可以在任意Target中访问。示例代码如下:
class Build : NukeBuild { public static int Main () => Execute<Build>(x => x.Clean); Target Clean => _ => _ .Executes(() => { // 存储状态到Context Context.Add("StateToRestore", "I am needed in Restore Target"); }); Target Restore => _ => _ .DependsOn(Clean) .Executes(() => { // 从Context读取类型安全的状态 var stateToRestore = Context.Get<string>("StateToRestore"); Console.WriteLine(stateToRestore); }); }
如果需要更类型安全的访问,可以自定义Context的扩展方法,避免硬编码键名:
public static class BuildContextExtensions { private const string StateToRestoreKey = "StateToRestore"; public static void SetStateToRestore(this IContext context, string value) { context.Add(StateToRestoreKey, value); } public static string GetStateToRestore(this IContext context) { return context.Get<string>(StateToRestoreKey); } }
修改后的Target代码会更简洁:
Target Clean => _ => _ .Executes(() => { Context.SetStateToRestore("I am needed in Restore Target"); }); Target Restore => _ => _ .DependsOn(Clean) .Executes(() => { Console.WriteLine(Context.GetStateToRestore()); });
2. 复杂状态的封装(官方推荐实践)
如果需要共享的状态较多或结构复杂,可以封装一个独立的状态类,结合类成员变量使用——这虽然和你提到的类范围存储类似,但属于Nuke官方推荐的结构化实践,比零散的字段更易维护:
// 封装状态类 public class BuildState { public string StateToRestore { get; set; } // 可以添加更多状态属性 } class Build : NukeBuild { public static int Main () => Execute<Build>(x => x.Clean); // 初始化状态对象 private readonly BuildState _buildState = new BuildState(); Target Clean => _ => _ .Executes(() => { _buildState.StateToRestore = "I am needed in Restore Target"; }); Target Restore => _ => _ .DependsOn(Clean) .Executes(() => { Console.WriteLine(_buildState.StateToRestore); }); }
注意事项
Context的生命周期和Build实例一致,仅在当前构建流程中有效;- 避免在并行执行的Target中共享状态(除非使用线程安全的存储),因为Nuke默认可能并行执行无依赖的Target。
内容的提问来源于stack exchange,提问作者dvan123
相关产品推荐
相关产品推荐

