Repository navigation
|
Hi, I really like what you have build here and most use cases are nicely covered. However, in the past I have made builders use constructors with parameters for properties on the to-be-constructed object that are "required" to construct a sane object. Not making the default constructor available for the builder forced developers to to think about what they are constructing. Sometimes a named constructor like Did I miss something in the README or how would you deal with this? |
Replies: 3 comments
|
I'm not sure I understand the problem, you want to force the builder to have constructor with required fields for the given object the builder is constructing? But anyway it's something I can add as an additional feature. If I don't understand what you mean - could you provide some code sample of what is your target state you want to achieve? |
|
Thanks for the quick response. Sure, here is a simplified code example: public class Dto
{
[JsonConstructor]
private Dto() { }
public Dto(int lineNumber, string activity)
{
LineNumber = lineNumber;
Activity = activity;
}
public int LineNumber { get; set; }
public string Activity { get; set; } = string.Empty;
public List<string> Tags { get; set; } = [];
}
public class DtoBuilder
{
private int lineNumber;
private string activity;
private List<string> tags;
public DtoBuilder(int lineNumber, string activity)
{
this.lineNumber = lineNumber;
this.activity = activity;
tags = [];
}
public DtoBuilder WithLineNumber(int value)
{
lineNumber = value;
return this;
}
public DtoBuilder WithActivity(string value)
{
activity = value;
return this;
}
public DtoBuilder WithTag(params string[] values)
{
tags.AddRange(values);
return this;
}
public Dto Build() => new(lineNumber: lineNumber, activity: activity) { Tags = tags };
}The key thing here is that a Now you could say that the developer should simply know what a valid Named constructors can be helpful to communicate intent, but having a parameterless constructor available usually undercuts this somewhat. Obviously this boils down to "skill issues" and I am not sure if this, somewhat niche, problem should be solved by your library. Perhaps having the option to make the builder constructor(s) private would solve this by forcing the user to specify named constructors, i.e. : [MakeBuilder(typeof(Dto), GeneratePrivateConstructor = true)]
public partial class DtoBuilder
{
public static DtoBuilder Create(int lineNumber, string activity) => new().WithLineNumber(lineNumber).WithActivity(activity);
} |
|
Idea makes sense, the forced parameters to the builder weren't considered because the original purpose of the library was to help with unit testing, and in unit testing you don't need to be that strict. |
Idea makes sense, the forced parameters to the builder weren't considered because the original purpose of the library was to help with unit testing, and in unit testing you don't need to be that strict.
But in the case you showed for sure it sounds like a good idea, I'll move it to the issues tracker.