我可以在 Cake 脚本中定义可重用的 subroutine/function/method 吗?

Can I define a reusable subroutine/function/method within a Cake script?

我正在尝试 Cake (C# Make)。到目前为止,所有示例和文档都有脚本文件在委托中声明其所有代码,如下所示:

Task("Clean")
    .Does(() =>
{
    // Delete a file.
    DeleteFile("./file.txt");

    // Clean a directory.
    CleanDirectory("./temp");
});

但是,我对使用 Cake 感兴趣的原因之一是可以使用与编写代码类似的方式编写我的构建脚本,因为脚本使用基于 C# 的 DSL。这种可能性包括将我使用的代码分离到方法(或函数/子例程,任何合适的术语)中的能力,这样我就可以分离关注点并重用代码。例如,我可能想要 运行 多个 SKU 的同一组步骤。

虽然我意识到我可以使用 Script Aliases 创建我自己的单独的 DLL,但我想避免在构建时每次想要更改这些共享代码时都必须重新编译一个单独的项目脚本。有没有一种方法可以定义与普通 build.cake 文件内联的方法,这些方法仍然可以 运行 Cake 别名(例如,DeleteFile)并且可以从我的 Cake 任务中调用它们?

Cake 是 C#,因此您可以创建 classes,方法,就像在常规 C# 中一样

即在蛋糕文件

中声明一个class
public class MyClass
{
    public void MyMethod()
    {

    }

    public static void MyStaticMethod()
    {

    }
}

然后使用类似

的脚本
var myClass = new MyClass();

// Call instance method
myClass.MyMethod();

//Call static method
MyClass.MyStaticMethod();

Cake DSL 基于 Roslyn 脚本,因此存在一些差异,代码基本上已经在一个类型中,因此您可以声明一个没有 class 的方法以供重用

public void MyMethod()
{

}

然后可以像全局方法一样调用

MyMethod();

一些问题,执行 class 会改变作用域,因此您将无法访问别名/上下文和全局方法。您可以通过将 ICakeContext 作为参数传递给 class

来解决这个问题
public class MyClass
{
    ICakeContext Context { get; }
    public MyClass(ICakeContext context)
    {
        Context = context;
    }

    public void MyMethod()
    {
        Context.Information("Hello");
    }
}

然后像这样使用

// pass reference to Cake context
var myClass = new MyClass(Context);

// Call instance method which uses an Cake alias.
myClass.MyMethod();

您可以有扩展方法,但不能在 class 中,例如:

public static void MyMethod(this ICakeContext context, string message)
{
    context.Information(message);
}


Context.MyMethod("Hello");