-
Notifications
You must be signed in to change notification settings - Fork 10
1.3 Distributed process
Marjan Nikolovski edited this page Apr 9, 2021
·
1 revision
We use distributed process when we want to expose an endpoint to be consumed from a client, but a part of the logic should be executed in a background service. The endpoint path is generated by a convention of folder structure. For example if we have a process in our “Web” project with full class name Web.Processes.AddUser the path will be /api/Processes/AddUser
The distributed process contains 5 layers:
- Auth
- Validate
- Handle
- Map
- Work
A communication channel aspect must be configured on both web and background application for this distributed process to work.
public class MyRequestData : IDtoData
{
public string Input1 { get; set; }
public int Input2 { get; set; }
/// <summary>
/// Sanitize
/// </summary>
/// <param name="sanitizer"></param>
public void Sanitize(HtmlSanitizer sanitizer)
{
Input1 = sanitizer.Sanitize(Input1);
}
}
public class MyTransientData : ITransientData
{
public string Input1 { get; set; }
public int Input2 { get; set; }
}
[ApiProcess(HttpMethod = ApiProcessMethod.POST)]
public class MyDistributedProcess : DistributedProcess<MyTransientData, MyRequestData, VoidResult>
{
/// <summary>
/// Auth process
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public override VoidResult Auth(MyRequestData request)
{
return Ok();
}
/// <summary>
/// Validate process
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public override VoidResult Validate(MyRequestData request)
{
return Ok();
}
/// <summary>
/// Handle process
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public override VoidResult Handle(MyRequestData request)
{
return Ok();
}
/// <summary>
/// Map process
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public override MyTransientData Map(MyRequestData request, MethodResult<int> result)
{
return new MyTransientData
{
Input1 = request.Input1,
Input2 = request.Input2
};
}
/// <summary>
/// Background work process
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public override VoidResult Work(MyTransientData user)
{
return Ok();
}
}
- 1 or 2 in generic arguments
- VoidResult, MethodResult or ListResult out generic argument
- SignalsAuthorizeProcess and Critical attributes
- Validation with specification pattern
- ApiProcess attribute
- Context.HttpContext property with all http context information
public class UserDtoData : IDtoData, ITransientData
{
public string Email { get; set; }
public string Username { get; set; }
public string Password { get; set; }
/// <summary>
/// Sanitize
/// </summary>
/// <param name="sanitizer"></param>
public void Sanitize(HtmlSanitizer sanitizer)
{
Email = sanitizer.Sanitize(Email);
Username = sanitizer.Sanitize(Username);
Password = sanitizer.Sanitize(Password);
}
}
[ApiProcess(HttpMethod = ApiProcessMethod.POST)]
public class RegisterUser : DistributedProcess<UserDtoData, UserDtoData, MethodResult<int>>
{
[Import] private IUserRepository UserRepository { get; set; }
/// <summary>
/// Auth process
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public override MethodResult<int> Auth(UserDtoData user)
{
return Ok();
}
/// <summary>
/// Validate process
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public override MethodResult<int> Validate(UserDtoData user)
{
return BeginValidation()
.Validate(new UserHasEmailAndPassword(), user)
.ReturnResult();
}
/// <summary>
/// Handle process
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public override MethodResult<int> Handle(UserDtoData user)
{
var userId = UserRepository.Register(user);
return userId;
}
/// <summary>
/// Map process
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public override UserDtoData Map(UserDtoData request, MethodResult<int> result)
{
return request;
}
/// <summary>
/// Background work process
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public override VoidResult Work(UserDtoData user)
{
return Continue<SendEmail>().With(user.Email);
}
}