在 Rider 中折叠 class 字段和构造函数参数

Fold class fields and constructor parameters in Rider

我在一个 .NET 项目上使用 Rider,该项目有许多 class 注入大量服务并在文件顶部占用大量空间,如下所示:

public class MyCoolService: IMyCoolService
{
    private readonly IMyInjectedService1: myInjectedService1;
    private readonly IMyInjectedService2: myInjectedService2;
    private readonly IMyInjectedService3: myInjectedService3;
    private readonly IMyInjectedService4: myInjectedService4;
    private readonly IMyInjectedService5: myInjectedService5;
    private readonly IMyInjectedService6: myInjectedService6;
    private readonly IMyInjectedService7: myInjectedService7;
    private readonly IMyInjectedService8: myInjectedService8;
    private readonly IMyInjectedService9: myInjectedService9;
    private readonly IMyInjectedService10: myInjectedService10;
    private readonly IMyInjectedService11: myInjectedService11;
    private readonly IMyInjectedService12: myInjectedService12;
    private readonly IMyInjectedService13: myInjectedService13;
    private readonly IMyInjectedService14: myInjectedService14;
    private readonly IMyInjectedService15: myInjectedService15;
    private readonly IMyInjectedService16: myInjectedService16;
    private readonly IMyInjectedService17: myInjectedService17;
    private readonly IMyInjectedService18: myInjectedService18;
    private readonly IMyInjectedService19: myInjectedService19;
    private readonly IMyInjectedService20: myInjectedService20;

    public MyCoolService(IMyInjectedService1 myInjectedService1,
        IMyInjectedService2 myInjectedService2, IMyInjectedService3 myInjectedService3,
        IMyInjectedService4 myInjectedService4, IMyInjectedService5 myInjectedService5,
        IMyInjectedService6 myInjectedService6, IMyInjectedService7 myInjectedService7,
        IMyInjectedService8 myInjectedService8, IMyInjectedService9 myInjectedService9,
        IMyInjectedService10 myInjectedService10, IMyInjectedService11 myInjectedService11,
        IMyInjectedService12 myInjectedService12, IMyInjectedService13 myInjectedService13,
        IMyInjectedService14 myInjectedService14, IMyInjectedService15 myInjectedService15,
        IMyInjectedService16 myInjectedService16, IMyInjectedService17 myInjectedService17,
        IMyInjectedService18 myInjectedService18, IMyInjectedService19 myInjectedService19,
        IMyInjectedService20 myInjectedService20)
    {
        this.myInjectedService1 = myInjectedService1;
        this.myInjectedService2 = myInjectedService2;
        this.myInjectedService3 = myInjectedService3;
        this.myInjectedService4 = myInjectedService4;
        this.myInjectedService5 = myInjectedService5;
        this.myInjectedService6 = myInjectedService6;
        this.myInjectedService7 = myInjectedService7;
        this.myInjectedService8 = myInjectedService8;
        this.myInjectedService9 = myInjectedService9;
        this.myInjectedService10 = myInjectedService10;
        this.myInjectedService11 = myInjectedService11;
        this.myInjectedService12 = myInjectedService12;
        this.myInjectedService13 = myInjectedService13;
        this.myInjectedService14 = myInjectedService14;
        this.myInjectedService15 = myInjectedService15;
        this.myInjectedService16 = myInjectedService16;
        this.myInjectedService17 = myInjectedService17;
        this.myInjectedService18 = myInjectedService18;
        this.myInjectedService19 = myInjectedService19;
        this.myInjectedService20 = myInjectedService20;
    }
}

当我浏览代码时,我喜欢使用代码折叠来获得 class 的概览,然后展开并深入到我想要处理的特定部分。目前 Rider 可以自动折叠隐藏一些细节的构造函数主体:

public class MyCoolService: IMyCoolService
{
    private readonly IMyInjectedService1: myInjectedService1;
    private readonly IMyInjectedService2: myInjectedService2;
    private readonly IMyInjectedService3: myInjectedService3;
    private readonly IMyInjectedService4: myInjectedService4;
    private readonly IMyInjectedService5: myInjectedService5;
    private readonly IMyInjectedService6: myInjectedService6;
    private readonly IMyInjectedService7: myInjectedService7;
    private readonly IMyInjectedService8: myInjectedService8;
    private readonly IMyInjectedService9: myInjectedService9;
    private readonly IMyInjectedService10: myInjectedService10;
    private readonly IMyInjectedService11: myInjectedService11;
    private readonly IMyInjectedService12: myInjectedService12;
    private readonly IMyInjectedService13: myInjectedService13;
    private readonly IMyInjectedService14: myInjectedService14;
    private readonly IMyInjectedService15: myInjectedService15;
    private readonly IMyInjectedService16: myInjectedService16;
    private readonly IMyInjectedService17: myInjectedService17;
    private readonly IMyInjectedService18: myInjectedService18;
    private readonly IMyInjectedService19: myInjectedService19;
    private readonly IMyInjectedService20: myInjectedService20;

    public MyCoolService(IMyInjectedService1 myInjectedService1,
        IMyInjectedService2 myInjectedService2, IMyInjectedService3 myInjectedService3,
        IMyInjectedService4 myInjectedService4, IMyInjectedService5 myInjectedService5,
        IMyInjectedService6 myInjectedService6, IMyInjectedService7 myInjectedService7,
        IMyInjectedService8 myInjectedService8, IMyInjectedService9 myInjectedService9,
        IMyInjectedService10 myInjectedService10, IMyInjectedService11 myInjectedService11,
        IMyInjectedService12 myInjectedService12, IMyInjectedService13 myInjectedService13,
        IMyInjectedService14 myInjectedService14, IMyInjectedService15 myInjectedService15,
        IMyInjectedService16 myInjectedService16, IMyInjectedService17 myInjectedService17,
        IMyInjectedService18 myInjectedService18, IMyInjectedService19 myInjectedService19,
        IMyInjectedService20 myInjectedService20)
    {...}
}

然而,这会留下私有字段和构造函数参数。我最终做的是使用 Ctrl+. 自定义代码折叠来隐藏这些区域(然后我可以根据需要展开它们)。我的问题是每次都是手动过程。有没有办法让 Rider 将这些区域识别为可折叠并自动执行?

public class MyCoolService: IMyCoolService
{
    ...

    public MyCoolService(...)
    {...}
}

理想情况下,您不会将那么多服务注入单个 class。理想的方法是重构代码,没有那么多依赖项。

但是,这可能不是一个简单的选择,这是可以理解的。您可以做的一件事是使用 #region 语句包装代码。这告诉 IDE 折叠指定区域中的代码。

下面是一个示例,说明如何在您的示例中使用它

public class MyCoolService: IMyCoolService
{
    #region Injected properties

    private readonly IMyInjectedService1: myInjectedService1;
    private readonly IMyInjectedService2: myInjectedService2;
    private readonly IMyInjectedService3: myInjectedService3;
    private readonly IMyInjectedService4: myInjectedService4;
    private readonly IMyInjectedService5: myInjectedService5;
    private readonly IMyInjectedService6: myInjectedService6;
    private readonly IMyInjectedService7: myInjectedService7;
    private readonly IMyInjectedService8: myInjectedService8;
    private readonly IMyInjectedService9: myInjectedService9;
    private readonly IMyInjectedService10: myInjectedService10;
    private readonly IMyInjectedService11: myInjectedService11;
    private readonly IMyInjectedService12: myInjectedService12;
    private readonly IMyInjectedService13: myInjectedService13;
    private readonly IMyInjectedService14: myInjectedService14;
    private readonly IMyInjectedService15: myInjectedService15;
    private readonly IMyInjectedService16: myInjectedService16;
    private readonly IMyInjectedService17: myInjectedService17;
    private readonly IMyInjectedService18: myInjectedService18;
    private readonly IMyInjectedService19: myInjectedService19;
    private readonly IMyInjectedService20: myInjectedService20;

    #endregion

    public MyCoolService(
        IMyInjectedService1 myInjectedService1,
        IMyInjectedService2 myInjectedService2, IMyInjectedService3 myInjectedService3,
        IMyInjectedService4 myInjectedService4, IMyInjectedService5 myInjectedService5,
        IMyInjectedService6 myInjectedService6, IMyInjectedService7 myInjectedService7,
        IMyInjectedService8 myInjectedService8, IMyInjectedService9 myInjectedService9,
        IMyInjectedService10 myInjectedService10, IMyInjectedService11 myInjectedService11,
        IMyInjectedService12 myInjectedService12, IMyInjectedService13 myInjectedService13,
        IMyInjectedService14 myInjectedService14, IMyInjectedService15 myInjectedService15,
        IMyInjectedService16 myInjectedService16, IMyInjectedService17 myInjectedService17,
        IMyInjectedService18 myInjectedService18, IMyInjectedService19 myInjectedService19,
        IMyInjectedService20 myInjectedService20)
    {

        #region property assignments

        this.myInjectedService1 = myInjectedService1;
        this.myInjectedService2 = myInjectedService2;
        this.myInjectedService3 = myInjectedService3;
        this.myInjectedService4 = myInjectedService4;
        this.myInjectedService5 = myInjectedService5;
        this.myInjectedService6 = myInjectedService6;
        this.myInjectedService7 = myInjectedService7;
        this.myInjectedService8 = myInjectedService8;
        this.myInjectedService9 = myInjectedService9;
        this.myInjectedService10 = myInjectedService10;
        this.myInjectedService11 = myInjectedService11;
        this.myInjectedService12 = myInjectedService12;
        this.myInjectedService13 = myInjectedService13;
        this.myInjectedService14 = myInjectedService14;
        this.myInjectedService15 = myInjectedService15;
        this.myInjectedService16 = myInjectedService16;
        this.myInjectedService17 = myInjectedService17;
        this.myInjectedService18 = myInjectedService18;
        this.myInjectedService19 = myInjectedService19;
        this.myInjectedService20 = myInjectedService20;

        #endregion
    }
}

IDE就能折叠构造函数了。这是你的代码折叠后的样子

虽然我同意@tejas-parnerkar 的回答,但我想提供另一种观点。如果您必须注入那么多 class,这意味着 class 试图做太多事情,即它的职责可能没有正确界定。

如果您的class有这些方法:

class ChoreRunner
{
    private VacuumCleaner _vacuumCleaner;
    private Sink _sink;
    private WashingMachine _washingMachine;
    private Kitchen _kitchen;
    // ...other dependencies
    
    public Task SweepFloor() {}
    public Task DoDishes() {}
    public Task FeedKids() {}
    public Task DoLaundry() {}
    // ...
}

真正的解决方案是将那个“上帝”class 分解成更小的 class 具有严格约束责任的实体。

interface IChore
{
    Task Do(); 
}

class SweepFloor: IChore
{
    private VacuumCleaner _vacuum;
    public Task Do() {/* ... */}
}

class WashDishes: IChore
{
    private Sink _sink;
    private IDirtyDishSource _dirtyDishSource;

    // ...
    public Task Do() {/* ... */}
}

class Laundry: IChore
{
    private WashingMachine _washingMachine;
    private Dryer _dryer;
    // ...
    public Task Do() {/* ... */}
}

class FeedKids : IChore
{
    private Kitchen _kitchen;
    private IKidProvider _kidProvider;
    // ...
    public Task Do() {/* ... */}
}