# Functional DDD with C# Part 6: the application layer

# Introduction

Last article of the series: the application layer. We will talk about its role, how to write it in a functional style with just a few lines of code but also how to deal with asynchronism. For that, we will use all the concepts we have learned so far. Let's dive in and let's create sustainable software.

# A refresher on the functional architecture

Functional architecture is a rigorous clean or onion architecture. Its domain and application layers are written by applying the principles of functional programming: immutability, function composition, etc.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1680369363383/c8e3127c-688f-43ea-8860-48eb5320bc7a.png align="center")

# A functional application layer

[Remember](https://grenat.hashnode.dev/functional-ddd-with-c-part-2-functional-architecture), the application layer is an orchestrator between the infrastructure layer and the domain layer: the domain layer make the decisions and the infrastructure layer executes the necessary side effects (saving to a database, posting a message in a bus, ....) thanks to the application layer.

Let's take an example: adding a product to a catalog. The application layer will be responsible to perform the following steps:

1. Transform a `ProductDto` into a domain `Product`.
    
2. Check if the product reference already exists.
    
3. Save the product to the database.
    

We want these steps to be written in a functional style by creating a pipeline**.** We will use for that techniques we've learned so far: containers, `Bind()` and `Map()` functions.

# Creating the pipeline

## Creating the AddProduct() function

Let's create this function. We will complete it all along this article. It will look like this :

```C#
public static async OperationResultDto<ProductDto> AddProduct(
	AddProductDto addProductDto)
{
}
```

I have defined an `OperationResult<T>`: it will contain a value if no error happened during the operation, else it will contain an error.

## Railway-oriented programming

A word about railway-oriented programming first. As soon as something wrong happens in the flow, then it is switched towards an error path: the execution flow of the pipeline is interrupted and the error messages are returned.

In our pipeline, the execution flow will be automatically routed to the error path whenever an entity is in an invalid state, thanks to `Map()` and `Bind()` functions defined on the entities.

Here is a little drawing to help you understand. This programming style is extremely well explained by Scott Wlaschin [here](https://fsharpforfunandprofit.com/rop/).

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1680368879253/269a1774-d70a-41b7-9678-a3a2996003e1.png align="center")

## Identifying the signatures of the pipeline functions

First step to write our pipeline: identifying the signatures of the functions that we will use for each step.

To easily create our pipeline, we will use an `Entity<Product>` as we've learned in the previous articles.

Its steps will be as follows:

1. We need to transform a `ProductDto` into a domain `Product`. The signature of this function will be `ProductDto -> Entity<Product>`.
    
2. Next, we need to check if the product reference already exists. For that, we will create a function that takes a domain `Product` and a count of identical references as parameters. It will return an `Entity<Product>` in a valid state if no other references have been found in the database, else it will be in an invalid state. So the function's signature will be `Product -> int -> Entity<Product>`.
    
3. Next, we need to save the product. The saving will be done by a repository. It will take a domain `Product` as a parameter and will return the saved domain product as a response. The signature of such a function is `Product -> Product`.
    

Nevertheless, we have a problem to create our pipeline because the function's outputs are all different, thus preventing us to chain them using a fluent style. That is where `Bind()` and `Map()` functions will come into play.

## First step: converting a ProductDto to Entity&lt;Product&gt;

This first step is an easy one. We need transform a `ProductDto` into an `Entity<Product>`.

To do that, we simply define an extension method on the `ProductDto` class. I already have defined `Reference`, `Name` and `Price` Value Objects as explained in the [4th article](https://grenat.hashnode.dev/functional-ddd-with-c-part-4-value-objects) of this series. I then create the Product Entity using the guidelines of the [previous article](https://grenat.hashnode.dev/functional-ddd-with-c-part-5-entities-and-aggregates) of this series.

```C#
public static class AddProductDtoExtensions
{
	public static Entity<Product> ToProductEntity(this AddProductDto addProductDto)
	{
		return Product.CreateEmpty()
						.WithReference(addProductDto.Reference)
						.WithName(addProductDto.Name)
						.WithPrice(addProductDto.Price);
	}
}
```

If a value of the `ProductDto` is not or incorrectly filled in, then the value objects will return an error when they are instantiated: they act as control gates and a big advantage of that is that we don't need to provide any model validation in the Dtos thus avoiding code duplication between the domain layer and the infrastructure layer. The entity will then be created in an invalid state and all subsequent steps in the flow will be skipped.

Now let's complete `AddProduct()` function and let's call our new extension method to convert our `AddProductDto` into an `Entity<Product>`:

```C#
public static OperationResultDto<ProductDto> AddProduct(
	AddProductDto addProductDto)
{
	var p = addProductDto.ToProductEntity();

	return p.Match(
		Valid: (v) => new OperationResultDto<ProductDto>(v.ToProductDto()),
		Invalid: (e) => new OperationResultDto<ProductDto>(e)
	);
}
```

## Second step: verifying if the product reference exists

Let's create our verification function. It is a decision-making function, so you need to put in the domain layer. It returns an invalid `Entity<Product>` if the reference already exists:

```C#
public static Entity<Product> VerifyProductReference(Product product, int existingReferencesCount)
{
	if (existingReferencesCount > 0)
		return Entity<Product>.Invalid(new Error(string.Format(Messages.TheProductReferenceAlreadyExists, product.Reference.Value)));
	else
		return Entity<Product>.Valid(product);
}
```

In Grenat.Functional.DDD library, I added some implicit conversions to simplify writing. The following code is equivalent and shorter:

```csharp
public static Entity<Product> VerifyProductReference(Product product, int existingReferencesCount)
{
	if (existingReferencesCount > 0)
		return new Error(string.Format(Messages.TheProductReferenceAlreadyExists, product.Reference.Value)); // No need do call Entity<Product>.Invalid()
	else
		return product;
}
```

But how does this function chain to the result of the previous step? The previous function outputs an `Entity<Product>`, and we need a `Product`. Well, we will use the `Bind()` function. [Remember](https://grenat.hashnode.dev/functional-ddd-with-c-part-3-the-elevated-world), `Bind()` takes a function and it applies it to the wrapped value of the `Entity<T>` container.

Using `Bind()`, we can add simply add this new step to our `AddProduct()` function:

```C#
public static OperationResultDto<ProductDto> AddProduct(
	AddProductDto addProductDto,
	Func<string, int> CountProductReferences)
{
	var p = addProductDto.ToProductEntity()
			.Bind(VerifyProductReference, CountProductReferences(addProductDto.Reference));

	return p.Match(
		Valid: (v) => new OperationResultDto<ProductDto>(v.ToProductDto()),
		Invalid: (e) => new OperationResultDto<ProductDto>(e)
	);
}
```

## Third step: saving the product

I did not want to introduce an `Entity<Product>` container in the repository for that. It would have been useless to deal with an entity's state in the repository. The decision to save the product was already made by the domain layer, so the repository just have to execute. It does not need to verify the decision.

So the save function signature will be `Product -> Product`. Here again how to chain it to the function of the previous step? We need a `Product` whereas the previous step outputs an `Entity<Product>`. What's more, we need to get back an `Entity<Product>` to stay in the [elevated world](https://grenat.hashnode.dev/functional-ddd-with-c-part-3-the-elevated-world).

In that situation, `Map()` becomes handy. It is the same as `Bind()`, i.e. it takes a function and its parameters and it applies it to the wrapped value of the `Entity<T>` container.

But [instead](https://grenat.hashnode.dev/functional-ddd-with-c-part-3-the-elevated-world#heading-what-about-map), it lifts the function's output to the elevated world: `Entity<Product>`, allowing us to stick to the elevated world.

So let's update the `AddProduct()` function by adding this last step. I will not give the details of the `SaveProduct()` function, it is a classical repository function.

```csharp
public static OperationResultDto<ProductDto> AddProduct(
	AddProductDto addProductDto,
	Func<string, int> CountProductReferences
	Func<Product, Product> SaveProduct)
{
	var p = addProductDto.ToProductEntity()
			.Bind(Domain.Services.VerifyProductReference, CountProductReferences(addProductDto.Reference))
			.Map(SaveProduct);

	return p.Match(
		Valid: (v) => new OperationResultDto<ProductDto>(v.ToProductDto()),
		Invalid: (e) => new OperationResultDto<ProductDto>(e)
	);
}
```

Look how simple and clear is this code. Thanks to functional concepts, it deals with [error harvesting](https://grenat.hashnode.dev/functional-ddd-with-c-part-5-entities-and-aggregates#heading-error-harvesting) and error management without having to write any conditional logic. If another step needs to be added to the flow, well... just insert it into the pipeline using `Map()`, `Bind()` and `Entity<Product>`. Forget about errors, say goodbye to many bugs :)

# Dealing with asynchrony

All functions working with infrastructure resources must be asynchronous. Therefore, they must work with `Tasks`. But in C#, the syntax for representing functions returning Tasks is quite cumbersome… `Func<Task<T>>, Func<T, Task<R>>` …

To make our life easier, I added an `AsyncFunc` delegate to simplify this writing in [Grenat.Functional.DDD](https://github.com/BastienFoucher/Grenat.Functional.DDD):

* `Func<Task<T>>` is equivalent to `AsyncFunc<T>`.
    
* `Func<T, Task<R>>` is equivalent to `AsyncFunc<T, R>`.
    
* Etc., etc…
    

I also added asynchronous versions of `Map()` and `Bind()` : `MapAsync()` and `BindAsync()`. So, an asynchronous version of `AddProduct()` will be as follows:

```csharp
public static async Task<OperationResultDto<ProductDto>> AddProduct(
	AddProductDto addProductDto,
	AsyncFunc<string, int> CountProductReferences,
	AsyncFunc<Product, Product> SaveProduct)
{
	var p = await addProductDto.ToProductEntity()
					.BindAsync(VerifyProductReference, CountProductReferences(addProductDto.Reference))
					.MapAsync(SaveProduct);

	return p.Match(
		Valid: (v) => new OperationResultDto<ProductDto>(v.ToProductDto()),
		Invalid: (e) => new OperationResultDto<ProductDto>(e)
	);
}
```

# Improving performance with lazy evaluation

We have a performance problem with the previous code. It comes from this line of code:

```csharp
.BindAsync(VerifyProductReference, CountProductReferences(addProductDto.Reference))
```

Here, the function `CountProductReferences()` is called even if `Entity<Product>` is in an invalid state because it is given as a parameter.

To correct this problem, you should give a function as a parameter. An overload of `BindAsync()` exists for that in my library: it will call the given function only if `Entity<T>` is valid. This behavior is called lazy evaluation.

The correct statement is as follows:

```csharp
.BindAsync(VerifyProductReference, () => CountProductReferences(addProductDto.Reference))
```

# Calling AddProduct from an ASP.Net Core controller

Finally, the code to call the application layers' `AddProduct()` function from an ASP.Net Core controller could look like this:

```csharp
[HttpPost]
public async Task<ActionResult> AddProduct(AddProductDto addProductDto)
{
	var response = await CatalogOperations.AddProduct(
								addProductDto,
_productRepository.CountExistingProductReferences,
								_productRepository.AddProduct);
	if (response.Success)
		return Ok(response.Data);
	else
		return UnprocessableEntity(response.Errors);
}
```

As you can see, I pass **functions** as parameters instead of passing **interfaces** to `AddProduct()`. This functional approach makes the application much easier to test.

# Summary

* Use functional techniques to write a very thin application layer: railway-oriented programming, containers (`Entity<T>`, `ValueObject<T>`, ...) and their underlying operations: `Map()`, `Bind()`.
    
* Use my library [Grenat.Functional.DDD](https://github.com/BastienFoucher/Grenat.Functional.DDD) to help you with that.
    
* Don't forget to use asynchrony for better performance when handling out-of-process resources (databases, message bus, ....).
    
* Think of lazy evaluation for better performance: when calling a function that needs to handle time-consuming resources, give a function reference as a parameter and don't call it in case of an error.
    

# Final words about the series

This was the last article of this series. I hope you enjoyed it and that you learned new techniques for your daily C# DDD work. Feel free to contact me if you have any questions! :)

# About the cover image

IC 4628, the Prawn nebula. This pretty nebula is found in the Scorpius constellation. It is visible with good conditions only in the southern hemisphere. Total exposure time is about 9 hours.

[See it in large size in my portfolio](https://www.bastienfoucher.com/en/galleries/nebulae-hubble-palette/ic4628Crevette).
