Search code examples
c#.netrefactoringclean-architecturevalue-objects

Advice to refactor null checks?


I have a ValueObject's with some validation's like this:

public class ValueObject : SimpleValueObject<string> {
    private ValueObject (string value) : base(value) { }

    public static Result<ValueObject> Create(string value) {
        if (string.IsNullOrWhiteSpace(value)) {
            return Result.Failure<ValueObject>("ValueObjectIsRequired");
        }

        var valueObject = value.Trim();

        if (value.Length != 12) {
            return Result.Failure<ValueObject>("ValueObjectLengthRestriction");
        }

        if (value.Any(x => !char.IsDigit(x))) {
            return Result.Failure<ValueObject>("ValueObjectDigitRestriction");
        }
        
        return new ValueObject(valueObject);
    }
}

and class that uses it:

public class MyClass {
        public ValueObject? ValueObject { get; protected set; }
        // many more

In my Application Layer in DTO i have primitive types and then in handler convert them to ValueObject's:

var valueObject = request.ValueObject is not null ? ValueObject.Create(request.ValueObject).Value : null;

problem is there is many and many other valueObjects that can be null too. How to handle it more elegantly?

Or maybe its design problem?


Solution

  • There's nothing wrong by the idea of checking for null and having a fallback behavior. The problem in your case is that you have this logic implemented in an inline manner instead of implementing a method for this.

    Think of it this way: you may need to reuse this logic like 10-15 times or so. And then you will have 15 instances of the same pattern of code. And then, later on you realize that you not only need to check for ValueObject not to be null, but you will need to check for not empty too. So, you will have to apply this change 15 times instead of once each time you need to perform a change.

    Now, if you would implement a method and do this check inside of it, then you will only need to call that method at the 15 places you are needing the same pattern, so if you ever need to change it, you will need a single change inside the method instead.