Skip to main content
added 767 characters in body
Source Link
Fabio
  • 3.2k
  • 1
  • 20
  • 26

It is true that if you start using async-await it spreads as a zombie along application pipeline and you will be forced to use async everywhere.

Try to approach design from a bit different angle - domain logic care only about data.
So we can put all IO related code outside of domain layers as close to the top layers as possible.

1 Load required data asynchronouslyasynchronously
2 Pass data to the business logic
3 Process data synchronouslysynchronously
4 Return possible results
5 Save processed results asynchronouslyasynchronously

public class MyDomainObject
{
    public MyDomainObject(DomainContent content) => _content = content;

    public ProcessedContent DoSomething()
    {
        // Process given content
    }
}

// This implementation belongs to the "infrastructure" layer
public class MyDomainProcessor
{
    public MyDomainProcessor(IContentRepository repository)
    {
        _repository = repository;
    }

    public async Task ProcessAsync(Guid contentId)
    {
        var content = await _repository.GetContentBy(contentId);

        var processedContent = new MyDomainObject(content).DoSomething();

        await _repository.Save(processedContent);
    }
}

It is true that if you start using async-await it spreads as a zombie along application pipeline and you will be forced to use async everywhere.

Try to approach design from a bit different angle - domain logic care only about data.
So we can put all IO related code outside of domain layers as close to the top layers as possible.

1 Load required data asynchronously
2 Pass data to the business logic
3 Process data synchronously
4 Return possible results
5 Save processed results asynchronously

It is true that if you start using async-await it spreads as a zombie along application pipeline and you will be forced to use async everywhere.

Try to approach design from a bit different angle - domain logic care only about data.
So we can put all IO related code outside of domain layers as close to the top layers as possible.

1 Load required data asynchronously
2 Pass data to the business logic
3 Process data synchronously
4 Return possible results
5 Save processed results asynchronously

public class MyDomainObject
{
    public MyDomainObject(DomainContent content) => _content = content;

    public ProcessedContent DoSomething()
    {
        // Process given content
    }
}

// This implementation belongs to the "infrastructure" layer
public class MyDomainProcessor
{
    public MyDomainProcessor(IContentRepository repository)
    {
        _repository = repository;
    }

    public async Task ProcessAsync(Guid contentId)
    {
        var content = await _repository.GetContentBy(contentId);

        var processedContent = new MyDomainObject(content).DoSomething();

        await _repository.Save(processedContent);
    }
}
Source Link
Fabio
  • 3.2k
  • 1
  • 20
  • 26

It is true that if you start using async-await it spreads as a zombie along application pipeline and you will be forced to use async everywhere.

Try to approach design from a bit different angle - domain logic care only about data.
So we can put all IO related code outside of domain layers as close to the top layers as possible.

1 Load required data asynchronously
2 Pass data to the business logic
3 Process data synchronously
4 Return possible results
5 Save processed results asynchronously