Search code examples
c#.netjetbrains-iderider

Fold class fields and constructor parameters in Rider


I'm using Rider on a .NET project that has many classes that inject a large number of services and take up a lot of real estate at the top of the file like this:

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;
    }
}

As I navigate around the code I like to use code folding to get an overview of a class before unfolding and diving into the particular section I want to work on. At the moment Rider can automatically fold the constructor body which hides some detail:

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)
    {...}
}

However this leaves the private fields and constructor parameters. What I end up doing is using the Ctrl+. custom code folding to also hide these areas (then I can unfold them if needed). My issue is this is a manual process every time. Is there a way to get Rider to recognise these areas as foldable and do it automatically?

public class MyCoolService: IMyCoolService
{
    ...

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

Solution

  • Ideally you would not have that many services injected into a single class. The ideal approach would be to refactor the code, to not have so many dependencies.

    But, it is understandable that this may not be an straightforward option. One thing you can do is wrap the code, using a #region statement. This tells the IDE to fold the code in that specified region.

    Below is an example of how you can use this in your example

    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
        }
    }
    

    The IDE will be able to fold the constructor. This is how your code would look like after it's folded

    enter image description here