I have this API function:
public ResultEnum DoSomeAction(string a, string b, DateTime c, OtherEnum d,
string e, string f, out Guid code)
here is a slightly different one from Mikeys but what I am trying to do is make the whole thing as little to write as possible
public class DoSomeActionParameters
{
readonly string _a;
readonly int _b;
public string A { get { return _a; } }
public int B{ get { return _b; } }
DoSomeActionParameters(Initializer data)
{
_a = data.A;
_b = data.B;
}
public class Initializer
{
public Initializer()
{
A = "(unknown)";
B = 88;
}
public string A { get; set; }
public int B { get; set; }
public DoSomeActionParameters Create()
{
return new DoSomeActionParameters(this);
}
}
}
The DoSomeActionParameters is immutable as it can be and cannot be created directly as its default constructor is private
The initializer is not immutable, but only a transport
The usage takes advantage of the initializer on the Initializer (if you get my drift) And I can have defaults in the Initializer default constructor
DoSomeAction(new DoSomeActionParameters.Initializer
{
A = "Hello",
B = 42
}
.Create());
The parameters will be optional here, if you want some to be required you could put them in the Initializer default constructor
And validation could go in the Create method
public class Initializer
{
public Initializer(int b)
{
A = "(unknown)";
B = b;
}
public string A { get; set; }
public int B { get; private set; }
public DoSomeActionParameters Create()
{
if (B < 50) throw new ArgumentOutOfRangeException("B");
return new DoSomeActionParameters(this);
}
}
So now it looks like
DoSomeAction(new DoSomeActionParameters.Initializer
(b: 42)
{
A = "Hello"
}
.Create());
Still a little kooki I know, but going to try it anyway
Edit: moving the create method to a static in the parameters object and adding a delegate which passes the initializer takes some of the kookieness out of the call
public class DoSomeActionParameters
{
readonly string _a;
readonly int _b;
public string A { get { return _a; } }
public int B{ get { return _b; } }
DoSomeActionParameters(Initializer data)
{
_a = data.A;
_b = data.B;
}
public class Initializer
{
public Initializer()
{
A = "(unknown)";
B = 88;
}
public string A { get; set; }
public int B { get; set; }
}
public static DoSomeActionParameters Create(Action assign)
{
var i = new Initializer();
assign(i)
return new DoSomeActionParameters(i);
}
}
So the call now looks like this
DoSomeAction(
DoSomeActionParameters.Create(
i => {
i.A = "Hello";
})
);