2

Lets say I have the following method:

 public async Task<IList<AnalysisResult>> GetAnalysis(short year, bool unPlanned = false,
     Guid? departmentId = null, Guid? personnelId = null, CollarColor? collarColor = null,Guid? factoryId = null)
{
    ...
}

The method parameter list is quite long and difficult to manage. This is one of the lightest.

What I want to do is to automatically convert these parameter lists to DTO classes.

For example:

If I exemplify the above method:

public class GetAnalysisPayload
{
    public short Year {get;set;}
    public bool UnPlanned {get;set;}
    public Guid? DepartmentId {get;set;}
    ...
}

I used this feature of ReSharper, a product of JetBranins, but the application froze and closed without any response. Although I have repeated it many times, I could not solve the problem. Anybody else have an idea?

Mohamad Mousheimish
  • 1,641
  • 3
  • 16
  • 48
Samet Öz
  • 53
  • 2
  • 8
  • Have you tried `dynamic`? – Gusman Jun 19 '20 at 07:44
  • Wait, do you mean in runtime or design time? – Gusman Jun 19 '20 at 07:45
  • 1
    @Gusman Hi Gusman, the methods written in ancient times.Difficult to manage now and I want to manage them in dto. So just generate the dto class. It doesn't matter when. – Samet Öz Jun 19 '20 at 07:49
  • It's a tough one. On the one hand "best practice" is to pass primitives as parameters to methods in other layers of your application, but on the other, a code linter is going to complain about too many parameters. I would just do it by hand. – Captain Kenpachi Jun 19 '20 at 07:50
  • (He means design time) – Captain Kenpachi Jun 19 '20 at 07:51
  • I can fix the places that give error with my hand. but creating classes manually is more costly @CaptainKenpachi – Samet Öz Jun 19 '20 at 07:52
  • If ReSharper crashes I assume it's because the project is too big/complex for it to replace the entries. Contact with ReSharper support, they may help you with the crash. Else, think the possibility to roll your own tool that creates the classes extracting the parameters from those functions. – Gusman Jun 19 '20 at 07:55
  • how many of the are there and how many more do you think there will be... and do u intent to build a tracker to it doesnt do the already created onces? – Seabizkit Jun 19 '20 at 07:55
  • what im saying is it may just make a bucket load more sense to just work through them, creating them... even of there is a hundred even a thousand. but if there were say like 20 thousand... then i may write something. – Seabizkit Jun 19 '20 at 07:58
  • I do not know. I thought this was done before. it is necessary to create a tool for this job. and I need to write code manually. – Samet Öz Jun 19 '20 at 07:58
  • Even at a hundred I'd say it could make sense to partially automate it. I was thinking with some help of some textfile editor like notepad++ and some regex. You could speed up the process significantly. Edit and some powershell/C# to polish. – Pac0 Jun 19 '20 at 07:59
  • How about this one? https://stackoverflow.com/questions/36155068/how-to-auto-generate-poco-class-object-from-a-method-parameters – Samet Öz Jun 19 '20 at 08:00
  • @Seabizkit You write a tool-ish for half a day, execute it for the afternoon and it saves you the whole following day. Also, it sharpens your powershell / regex skills :). (which might be a risk indeed, it might take you more than half the day to figure out properly the script skills) – Pac0 Jun 19 '20 at 08:03
  • 1
    Id reinstall/repair resharper, ctrl+shft+r ==> Transform parameters ==> enter. yeet – TheGeneral Jun 19 '20 at 08:18
  • i agree with @TheGeneral ....@Pac0, please by all means write the reflection to scan c# classes or even harder the regex which have params, then create anonymous Dto objects which im insure how you would name or store. the scope keeps growing... u could literally be done in a day... where as creating a ....tool. mmm i think do what TheGeneral suggested is much better but please do share the script when done. – Seabizkit Jun 19 '20 at 09:33

1 Answers1

0

Here is my dirty-but-help-a-bit method, mainly regex stuff.

! Answer in progress, just saving from time to time to avoid the dreaded back button

1: cleaning: format

Make sure the declarations are all in one line per function, IMO that will help sorting that out.

input:

 public async Task<IList<AnalysisResult>> GetAnalysis(short year, bool unPlanned = false,
     Guid? departmentId = null, Guid? personnelId = null, CollarColor? collarColor = null,Guid? factoryId = null)
{
    ...
}

 public async Task<IList<AnalysisResult>> GetOtherStuff(string foo = "bar", bool foobar = false, Guid? factoryId = null)
{
    ...
}

REGEX: ,\r\n

REPLACE BY: ,

output :

 public async Task<IList<AnalysisResult>> GetAnalysis(short year, bool unPlanned = false,     Guid? departmentId = null, Guid? personnelId = null, CollarColor? collarColor = null,Guid? factoryId = null)
{
    ...
}

 public async Task<IList<AnalysisResult>> GetOtherStuff(string foo = "bar", bool foobar = false, Guid? factoryId = null)
{
    ...
}

2: more cleaning: filter and create individual files

For this, need to work in a dedicated folder.

Take your input file from the result above. In the script below, it's "input.cs"

Let's take only the lines starting by "public" or "public async Task" if they're all async.

Create a script like filter.ps1

$regex = "^\s*public async Task[^(]*\s+([^(]+)" #capture the name of the function, i.e. the part before the opening parenthesis and space after Task<... type
get-content input.cs | % { if($_ -match $regex) {Set-Content -Path "$($matches[1])Payload.cs" -Value $_ } }

and execute it in the folder where only the script and the file input.cs are present.

Disclaimer: in the above code, I assume you don't have parenthesis, or space in the return type of the function! That could happen if you have some generic method with several type parameters, or Tuples.

output : 2 separate files, GetAnalysisPayload.cs and GetOtherStuffPayload.cs each with only the function declaration line.

3: split each line cleverly

Split on ( and ,, with some clever format, that will give the "DTO class header" first, and the list of parameters.

(regex / powershell code to be given)

That might get messy depending what you have at this step, but if functions are like your example, it could give you a pretty close approximation of what you need at this step already..

Then

With some time (a couple of hours?) I would have polished that with a Powershell script or C# console app, to save you part of the "unavoidable" remaining manual work.

for instance, add the "using" statements needed on top of each file.

I'm quoting "unvoidable", because it is told at night that some Regex wizards out there are able to take care of this job with regexes only.

Pac0
  • 21,465
  • 8
  • 65
  • 74