Skip to main content

Application Layer

The application layer serves as a mediator between the UI and the domain layers. Here you can define the job(s) certain action is expected to perform. It is a thin layer that will, usually, just reference the domain layer, but it may contain some workflow logic (never business logic), for example when you need to access more than one domain service:

YourProject.Application/Services/CustomAppService.cs
public class CustomAppService : BaseAppService, IJointAppService
{
public CustomAppService(IServiceProvider serviceProvider) : base(serviceProvider) { }

public async Task<OperationResult> PerformAction(object data)
{
var ds1 = await GetDomainService<IAction1DomainService>().Action1(data);
var ds2 = await GetDomainService<IAction2DomainService>().Action2(ds1);

return new OperationResult {
IsSuccessful = ds2.IsSuccessful,
Result = ds2
};
}
}
info

If it wasn't for this layer, if we ever decided to invoke our domain layer from another UI (let's say we changed our console app for a WebAPI one, for example), we'd need to rewrite the logic.

All services inherit from BaseService containing the following methods:

MethodSignatureDescription
ToEntityTEntity ToEntity<TEntity>(object source)Maps the source object to the entity type requested.
ToResponseTResponse ToResponse<TResponse>(object source)Maps the source object (entity) to the response type requested.
MapToTResponse MapTo<TResponse>(object source)Maps the source object to the type requested.
GetDomainServiceTDomainService GetDomainService<TDomainService>()Gets a domain service.
tip

You can always add extra methods to your service.

Let's explore the available structures provided by the UpDevs SDK:

Base

Provides the basic structure for all application services. It is the simplest form an app service can take.

Interface

YourProject.Contracts/Application/IMyAppService.cs
public interface IMyAppService : IAppService
{
// ... Methods' signatures
}

Implementation

YourProject.Application/Services/MyAppService.cs
public class MyAppService : BaseAppService, IMyAppService
{
public MyAppService(IServiceProvider serviceProvider) : base(serviceProvider) { }

// ... Methods
}

List

Inherits from BaseAppService and adds extra functionality to implement the listing behavior. Requires a response type to be informed (this is the type of the model that represents the entity as it's returned to the outside - it can have a Response or Model suffix depending on your structure for this entity).

info

The interface used for the related domain service must be provided here (see Implementation).

Methods Provided

info

They all have async options - ending with Async.

MethodSignatureDescription
ListPagedListModel<TResponse> List(SearchRequest? searchModel)Retrieves the entities found as a paged list based on the query.
GetByIdsTResponse[] GetByIds<TId>(TId[] ids)Retrieves a list of entities using the informed IDs.

Interface

YourProject.Contracts/Application/IMyAppService.cs
public interface IMyAppService : IListAppService<MyResponse>
{
// ... Other methods' signatures
}

Implementation

YourProject.Application/Services/MyAppService.cs
public class MyAppService : BaseListAppService<IMyDomainService, MyResponse>, IMyAppService
{
public MyAppService(IServiceProvider serviceProvider) : base(serviceProvider) { }

// ... Other methods
}

Inherits from BaseListAppService and adds extra functionality to implement the search behavior. Requires a response type to be informed (this is the type of the model that represents the entity as it's returned to the outside - it can have a Response or Model suffix depending on your structure for this entity).

info

The interface used for the related domain service must be provided here (see Implementation).

Methods Provided

info

They all have async options - ending with Async. Also includes the methods in BaseListAppService.

MethodSignatureDescription
SearchPagedListModel<TResponse> Search(SearchRequest? searchModel)Retrieves the entities found as a paged list based on the query.
GetCsvbyte[] GetCsv(CsvSearchRequest? searchModel)Retrieves the entities found as a CSV structure based on the query.

Interface

YourProject.Contracts/Application/IMyAppService.cs
public interface IMyAppService : ISearchAppService<MyResponse>
{
// ... Other methods' signatures
}

Implementation

YourProject.Application/Services/MyAppService.cs
public class MyAppService : BaseSearchAppService<IMyDomainService, MyResponse>, IMyAppService
{
public MyAppService(IServiceProvider serviceProvider) : base(serviceProvider) { }

// ... Other methods
}

Entity (CRUD)

Inherits from BaseSearchAppService and adds extra functionality to implement the CRUD behavior. Requires an input (this is the type of the model that represents the entity as it's sent to service - it can have an Input or Model suffix depending on your structure for this entity) and response (this is the type of the model that represents the entity as it's returned to the outside - it can have a Response or Model suffix depending on your structure for this entity) types to be informed .

info

The interface used for the related domain service must be provided here (see Implementation).

Methods Provided

info

They all have async options - ending with Async. Also includes the methods in BaseSearchAppService.

MethodSignatureDescription
GetTResponse? Get(params object[] keyValues)Retrieves an entity using its ID(s).
GetTResponse? Get<TId>(TId id)Retrieves an entity using its ID.
CreateTResponse Create(TInput data)Creates a new record using the input data.
CreateTResponse Create(TInput data, IFormFileCollection files)Creates a new record using the input data and associated files.
UpdateTResponse Update(TInput data)Updates the existing record using the input data.
UpdateTResponse Update(TInput data, IFormFileCollection files)Updates the existing record using the input data and associated files.
Deletebool Delete(params object[] keyValues)Removes an entity using its ID(s).
DeleteManybool DeleteMany<TId>(TId[] ids)Removes the entities matching the informed IDs.

Interface

note

If you use the Model pattern instead of Input/Response for this entity, you only need to provide the model type once.

YourProject.Contracts/Application/IMyAppService.cs
public interface IMyAppService : IEntityAppService<MyModel>
{
// ... Other methods' signatures
}
YourProject.Application/Services/MyAppService.cs
public interface IMyAppService : IEntityAppService<MyInput, MyResponse>
{
// ... Other methods' signatures
}

Implementation

note

If you use the Model pattern instead of Input/Response for this entity, you only need to provide the model type once.

YourProject.Application/Services/MyAppService.cs
public class MyAppService : BaseEntityAppService<IMyDomainService, MyModel>, IMyAppService
{
public MyAppService(IServiceProvider serviceProvider) : base(serviceProvider) { }

// ... Other methods
}
YourProject.Application/Services/MyAppService.cs
public class MyAppService : BaseEntityAppService<IMyDomainService, MyInput, MyResponse>,
IMyAppService
{
public MyAppService(IServiceProvider serviceProvider) : base(serviceProvider) { }

// ... Other methods
}