To materialize ORM objects, reflection is most often used. EF can reach a protected constructor, but programmers can’t. They will have to create the correct person identified by their TIN. The designer is equipped with guards. It just won’t work to create an invalid object. The ValidateProperties Extension method calls validation by DataAnnotation – attributes, and NullIfEmpty does not allow empty strings to be passed.
public static class Extensions
{
public static void ValidateProperties(this object obj)
{
var context = new ValidationContext(obj);
Validator.ValidateObject(obj, context, true);
}
public static string NullIfEmpty(this string str)
=> string.IsNullOrEmpty(str) ? null : str;
}
To validate the ID, an attribute of the following form is specially written:
public class InnAttribute : RegularExpressionAttribute
{
public InnAttribute() : base(@"^(\d{10}|\d{12})$")
{
ErrorMessage = "ID must be a sequence of 10/12 digits.";
}
public InnAttribute(CivilLawSubject civilLawSubject)
: base(civilLawSubject == CivilLawSubject.Individual
? @"^\d{12}$"
: @"^\d{10}$")
{
ErrorMessage = civilLawSubject == CivilLawSubject.Individual
? "Must be a 12-digit sequence."
: "Must be a 10-digit sequence.";
}
}
The parameterless constructor is declared protected to be used only by ORM. For materialization, reflection is used, so the access modifier is not a hindrance. Both required fields are passed to the “real” constructor. The rest of the fields in the context of the system are optional and are filled in by the company representative later.