Using struct to enforce validation of built-in type

Commonly domain objects have properties which can be represented by a built-in type but whose valid values are a subset of the values which may be represented by that type.

In these cases, the value can be stored using the built-in type but it is necessary to ensure values are always validated at the point of entry, otherwise we might end up working with an invalid value.

One way to solve this is to store the value as a custom struct which has a single private readonly backing field of the built-in type and whose constructor validates the provided value. We can then always be sure of only using validated values by using this struct type.

We can also provide cast operators from and to the underlying built-in type so that values can seamlessly enter and exit as the underlying type.

Take as an example a situation where we need to represent the name of a domain object, and valid values are any string which is between 1 and 255 characters in length inclusive. We could represent this using the following struct:

public struct ValidatedName : IEquatable<ValidatedName>
{
    private readonly string _value;

    private ValidatedName(string name)
    {
        _value = name;
    }

    public static bool IsValid(string name)
    {
        return !String.IsNullOrEmpty(name) && name.Length <= 255;
    }

    public bool Equals(ValidatedName other)
    {
        return _value == other._value;
    }

    public override bool Equals(object obj)
    {
        if (obj is ValidatedName)
        {
            return Equals((ValidatedName)obj);
        }
        return false;
    }

    public static implicit operator string(ValidatedName x)
    {
        return x.ToString();
    }

    public static explicit operator ValidatedName(string x)
    {
        if (IsValid(x))
        {
            return new ValidatedName(x);
        }
        throw new InvalidCastException();
    }

    public static bool operator ==(ValidatedName x, ValidatedName y)
    {
        return x.Equals(y);
    }

    public static bool operator !=(ValidatedName x, ValidatedName y)
    {
        return !x.Equals(y);
    }

    public override int GetHashCode()
    {
        return _value.GetHashCode();
    }

    public override string ToString()
    {
        return _value;
    }
}

The example shows the to-string cast as implicit as this can never fail but the from-string cast as explicit as this will throw for invalid values, but of course these could both be either implicit or explicit.

Note also that one can only initialize this struct by way of a cast from string, but one can test whether such a cast will fail in advance using the IsValid static method.

This would seem to be a good pattern to enforce validation of domain values which can be represented by simple types, but I don’t see it used often or suggested and I’m interested as to why.

So my question is: what do you see as being the advantages and disadvantages of using this pattern, and why?

If you feel that this is a bad pattern, I would like to understand why and also what you feel is the best alternative.

NB I originally asked this question on Stack Overflow but it was put on hold as primarily opinion-based (ironically subjective in itself) – hopefully it can enjoy more success here.

Above is the original text, below a couple more thoughts, partly in response to the answers received there before it went on hold:

  • One of the major points made by the answers was around the amount of boiler plate code necessary for the above pattern, especially when many such types are required. However in defence of the pattern, this could be largely automated using templates and actually to me it doesn’t seem too bad anyway, but that is just my opinion.
  • From a conceptual point of view, does it not seem strange when working with a strongly-typed language such as C# to only apply the strongly-typed principle to composite values, rather than extending it to values which can be represented by an instance of a built-in type?

1

This is fairly common in ML-style languages like Standard ML/OCaml/F#/Haskell where it’s much easier to create the wrapper types. It provides you with two benefits:

  • It allows a piece of code to enforce that a string has undergone validation, without having to take care of that validation itself.
  • It allows you to localize the validation code in one place. If a ValidatedName ever contains an invalid value, you know the error is in the IsValid method.

If you get the IsValid method right, you have a guarantee that any function that receives a ValidatedName is in fact receiving a validated name.

If you need to do string manipulations you can add a public method that accepts a function that takes a String (the value of the ValidatedName) and returns a String (the new value) and validates the result of applying the function. That eliminates the boilerplate of getting the underlying String value and re-wrapping it.

A related use for wrapping values is to track their provenance. E.g. C-based OS APIs sometimes give handles for resources as integers. You can wrap the OS APIs to instead use a Handle structure and only provide access to the constructor to that part of the code. If the code that produces the Handles is correct, then only valid handles will ever be used.

what do you see as being the advantages and disadvantages of using this pattern, and why?

Good:

  • It is self contained. Too many validation bits have tendrils reaching into different places.
  • It helps self-documentation. Seeing a method take a ValidatedString makes it much clearer about the semantics of the call.
  • It helps limit validation to one spot rather than needing to be duplicated across public methods.

Bad:

  • The casting trickery is hidden. It’s not idiomatic C#, so can cause confusion when reading the code.
  • It throws. Having strings that don’t meet validation isn’t an exceptional scenario. Doing IsValid before the cast is a little unweildy.
  • It can’t tell you why something is invalid.
  • The default ValidatedString is not valid/validated.

I’ve seen this sort of thing more often with User and AuthenticatedUser sort of things, where the object actually changes. It can be a fine approach, though it seems out of place in C#.

9

Your way is quite heavy and intensive. I typically define domain entities like:

public class Institution
{
    private Institution() { }

    public Institution(int organizationId, string name)
    {
        OrganizationId = organizationId;            
        Name = name;
        ReplicationKey = Guid.NewGuid();

        new InstitutionValidator().ValidateAndThrow(this);
    }

    public int Id { get; private set; }
    public string Name { get; private set; }        
    public virtual ICollection<Department> Departments { get; private set; }

    ... other properties    

    public Department AddDepartment(string name)
    {
        var department = new Department(Id, name);
        if (Departments == null) Departments = new List<Department>();
        Departments.Add(department);            
        return department;
    }

    ... other domain operations
}

In the entity’s constructor, validation is triggered using FluentValidation.NET, to make sure you cannot create an entity with invalid state. Note that properties are all readonly – you can only set them through the constructor or dedicated domain operations.

Validation of this entity is a separate class:

public class InstitutionValidator : AbstractValidator<Institution>
{
    public InstitutionValidator()
    {
        RuleFor(institution => institution.Name).NotNull().Length(1, 100).WithLocalizedName(() =>   Prim.Mgp.Infrastructure.Resources.GlobalResources.InstitutionName);       
        RuleFor(institution => institution.OrganizationId).GreaterThan(0);
        RuleFor(institution => institution.ReplicationKey).NotNull().NotEqual(Guid.Empty);
    }  
}

These validators can also be easily reused, and you write less boilerplate code. And another advantage is that it’s readable.

3

I like this approach to value types. The concept is great, but I have some suggestions/complains about the implementation.

Casting: I don’t like use of casting in this case. The explicit from-string cast is not a problem, but there is not much difference between (ValidatedName)nameValue and new ValidatedName(nameValue). So it seems kind of unnecessary. The implicit to-string cast is worst problem. I think that getting actual string value should be more explicit, because it might accidentally get assigned to string and compiler won’t warn you about possible “loss of precision”. This kind of precision loss should be explicit.

ToString: I prefer using ToString overloads just for debugging purposes. And I don’t think returning the raw value for it is a good idea. This is same issue as with implicit to-string conversion. Getting the internal value should be explicit operation. I believe you are trying to make the structure behave as a normal string to the outside code, but I think in doing so, you are loosing some of the value you get from implementing this kind of type.

Equals and GetHashCode: Structs are using structural equality by default. So your Equals and GetHashCode are duplicating this default behavior. You can remove them and it will be pretty much same thing.

5

I just happened to run across this question… turns out, back in 2015, the same year you posted this, I had a very similar idea, and I turned it into an open source library — RT.ValueFilters.

It has all of 2 stars lol, but I’ve been using it pretty much the whole time since, and the only annoyance is losing the syntactic sugar of auto-properties. I believe this library addresses most of the concerns raised in the discussion.

https://github.com/richardtallent/RT.ValueFilter

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật