0

I have the following value object code which validates CustCode by some expensive database operations.

public class CustCode : ValueObject<CustCode>
{
    private CustCode(string code) { Value = code; }

    public static Result<CustCode> Create(string code)
    {
        if (string.IsNullOrWhiteSpace(code))
            return Result.Failure<CustCode>("Code should not be empty");

        // validate if the value is still valid against the database. Expensive and slow
        if (!ValidateDB(code)) // Or web api calls
            return Result.Failure<CustCode>("Database validation failed.");

        return Result.Success<CustCode>(new CustCode(code));
    }

    public string Value { get; }

    // other methods omitted ...
}

public class MyEntity 
{
    CustCode CustCode { get; }
    ....

It works fine when there is only one or a few entity instances with the type. However, it becomes very slow for method like GetAll() which returns a lot of entities with the type.

public async IAsyncEnumerable<MyEntity> GetAll()
{
    string line;
    using var sr = File.OpenText(_config.FileName);
    while ((line = await sr.ReadLineAsync()) != null)
    {
        yield return new MyEntity(CustCode.Create(line).Value); // CustCode.Create called many times
    }
}

Since data in the file was already validated before saving so it's actually not necessary to be validated again. Should another Create function which doesn't validate the value to be created? What's the DDD idiomatically way to do this?

ca9163d9
  • 27,283
  • 64
  • 210
  • 413

2 Answers2

0

I generally attempt not to have the domain call out to retrieve any additional data. Everything the domain needs to do its job should be passed in.

Since value objects represent immutable state it stands to reason that once it has managed to be created the values are fine. To this end perhaps the initial database validation can be performed in the integration/application "layer" and then the CustCode is created using only the value(s) provided.

Eben Roux
  • 12,983
  • 2
  • 27
  • 48
0

Just wanted to add an additional point to @Eben Roux answer:

In many cases the validation result from a database query is dependent on when you run the query.

For example when you want to check if a phone number exists or if some product is in stock. The answers to those querys can change any second, and though are not suited to allow or prevent the creation of a value object.

You may create a "valid" object, that is (unknowingly) becoming invalid in the very next second (or the other way around). So why bother running an expensive validation, if the validation result is not reliable.

Benjamin M
  • 23,599
  • 32
  • 121
  • 201