c# 3.0 - Problems writing C# method parameter validation that supports fluent interface (call chaining) -
i'm trying write generic method parameter validation functionality can chained (fluent interface) attach more , more validations/checks like:
public void somemethod(user user, string description) { parameterhelper .create(() => user) .rejectnull(); parameterhelper .create(() => description) .rejectnull() .rejectemptystring(); // luxurious parameterhelper .create(() => new { user = user, desc = description }) .rejectnull(o => o.user) .rejectnull(o => o.desc) .rejectemptystring(o => o.desc); }
i use helper class test method parameters values before using them (most of time null
tested).
current state of affairs
i first started writing static helper class without create()
method like:
public static class parameterhelper { public static void rejectnull(expression<func<t>> expr) { if (expr.compile()().equals(default(t))) { memberexpression param = (memberexpression)expr.body; throw new argumentnullexception(param.member.name); } } }
but doesn't allow chaining. that's why created create()
method return can used chained extension methods.
the problem
- i avoid multiple
compile()
calls,create()
method should returnfunc<t>
, reject methods should extension methods offunc<t>
. - if
create()
returnfunc<t>
don't chance read parameter names should supplied various exceptions (usingmemberexpression
). - if return
expression<func<t>>
instead have callcompile()
in eachreject
extension method.
questions
- is there c# library kind of chaining?
- if not, suggest how should done? examples web warmly welcome.
additional note
i should point out complex/long validation invocation code not option here, because current validation done like:
if (user == null) { throw new argumentnullexception("user"); }
or
if (string.isnullorempty(description)) { throw new argumentnullexception("description"); }
which has 2 major drawbacks:
- i repeat same lines of code on , over
- it uses magic strings
so validation should done 1 liner per check described above in desired scenario.
there simple way implement such fluent interface. 'parameterhelper.create' method should return instance of class (this class named requirements
below). instance should hold expression passed create
. class should have require...
instance methods validate expression , return this
. requirements
class can private class inside parameterhelper
. introduce interface requirements chain (this interface named irequirements
below. sample:
public static class parameterhelper { public static irequirements create<t>(expression<func<t>> expression) { return new requirements{ expression = expression }; } private class requirements<t> : irequirements { public readonly expression<func<t>> expression { get; set; } public irequirements rejectnull() { if (expression .compile()().equals(default(t))) { memberexpression param = (memberexpression)expression.body; throw new argumentnullexception(param.member.name); } return this; } // other require... methods implemented in same way } } public interface irequirements { irequirements rejectnull(); }
this approach allow implementing luxurious
solution - need add corresponding parameters reject...
methods. need make irequirements
interface generic.
Comments
Post a Comment