Aplicación

La plataforma Devprime proporciona una estrategia completa de arquitectura de software, y el componente “Aplicación” juega un papel clave en este enfoque, ya que es responsable de habilitar interfaces con los otros componentes en un escenario donde las capas están desacopladas.

Introducción a la aplicación Devprime

La estructura predeterminada del proyecto “Aplicación” comienza con una carpeta llamada “EventHandlers” y un archivo “EventHandlers.cs” para registrar y mapear el “Evento de dominio” con el “Controlador de eventos”.

Al activar un “Evento de dominio” en la regla de negocio, se activará un “Controlador de eventos” con código que interactúa con la capa de tecnología.

Además, existe una carpeta para la inclusión de Interfaces, que en este contexto incluye solo el archivo “IExtension.cs”, responsable de habilitar las personalizaciones del proyecto a través de Extensiones de Adaptador.

Plataforma/Arquitectura/Aplicación Devprime

El archivo Application.csproj contiene la configuración predeterminada del proyecto y no es necesario incluir ninguna dependencia adicional. De acuerdo con la estrategia de arquitectura, este proyecto tiene una referencia al proyecto Domain para conectarse a las reglas de negocio del proyecto.

La estrategia de DevOps debe actualizar el parámetro Version con el identificador de la nueva versión de la aplicación de microservicios.

La referencia relacionada con Devprime Stack debe ser la misma en todos los proyectos, y puede actualizarla automáticamente ejecutando el comando dp stack, proporcionado por la CLI de Devprime y ejecutado en la carpeta principal del proyecto.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// Application.csproj
<Project Sdk="Microsoft.NET.Sdk">
	<PropertyGroup>
		<TargetFramework>net7.0</TargetFramework>
		<Version>1.0.0.0</Version>
	</PropertyGroup>
	<PropertyGroup>
      <ProjectGuid>{1ebcdb06-5294-4b06-9c45-1a8d299278d1}</ProjectGuid>
    </PropertyGroup>		
	<ItemGroup>
		<PackageReference Include="devprime.stack.foundation" Version="7.0.59" />
  	</ItemGroup>
	<ItemGroup>
		<ProjectReference Include="..\Domain\Domain.csproj" />
	</ItemGroup>
</Project>

Implementaciones estandarizadas en la aplicación

Uno de los pilares importantes que ofrece la plataforma Devprime es la estandarización del desarrollo de software y en este punto del proyecto de Aplicación ya es posible seguir algunas estrategias de organización de carpetas y archivos que permiten escalar los equipos de desarrollo de forma estandarizada.

En el ejemplo siguiente se muestra un ejemplo de inclusión de un “Application Services” que recibe un evento en una API y un repositorio de MongoDB mediante el adaptador de estado. Este procedimiento se puede realizar manualmente implementando cada carpeta y archivo, o utilizando el comando dp init ofrecida por la CLI de Devprime que analiza las reglas de negocio en Domain y realiza las implementaciones.

Artículos importantes:

  • En la carpeta “Servicios” se ha implementado el archivo “OrderServices.cs” que es un “Servicio de Aplicación” y en la carpeta Modelo en Servicios / Pedido / Modelo los objetos de entrada y salida “Order.cs y Item.cs” utilizados en el “Servicio de Aplicación”.
  • En la carpeta “Interfaces/Services” se ha implementado el archivo “IOrderServices.cs” que define la interfaz del servicio de aplicaciones.
  • En la carpeta “Interface / Adapters / State” se han implementado las interfaces “IOrderState.cs”, que actúan como HUB para los repositorios en el Estado del Adaptador, y “IOrderRepository.cs”, que se conecta al repositorio implementado en el Adaptador de Estado.
  • En la carpeta “Interfaz / Adaptadores / Extensiones”, encontramos la interfaz “IExtensions.cs”, la cual no cubriremos en este momento, ya que se detallará en el tema Extensiones.
  • En la carpeta “EventHandlers” se ha implementado el archivo “EventHandler.cs”, que funciona como HUB para la asignación de Handlers, y los archivos “CreateOrderEventHandler.cs” y “OrderCreatedEventHandler.cs” que actúan como Handlers. También se implementaron los modelos en “EventHandlers / Order / Model”, que se utilizan en las conversiones y parámetros de paso por parte de los Handlers.

Plataforma/Arquitectura/Aplicación Devprime

Explorar el flujo para la implementación de aplicaciones

El proyecto Application funciona como una capa de transporte en esta estrategia en la que la arquitectura de software está desacoplada y la conexión se produce a través de una estrategia de inversión de dependencias (DI).

#1 - Implementación de los modelos Order.cs / Item.cs
En la estructura de la plataforma Devprime, la carpeta para la implementación de los “Modelos” para los “Servicios de Aplicaciones” se encuentra en “Core > Servicios > de Aplicaciones” y se utilizan para la estandarización de parámetros y mapeos.

Un ejemplo común que se encuentra en las implementaciones de estos modelos es la relación con los objetos de negocio presentes en el proyecto de dominio, como se representa en el bloque de código siguiente. Con este enfoque, el “Dominio” no conoce la “Aplicación”.

1
2
3
4
5
6
    public virtual Domain.Aggregates.Order.Order ToDomain(Guid id)
    {
        var _order = new Domain.Aggregates.Order.Order();
        _order.ID = id;
        return _order;
    }

Para obtener más detalles, explore los dos modelos a continuación:

#2 - Implementación de la interfaz IOrderService.cs
En la estructura de la plataforma Devprime, la carpeta para implementar las interfaces de “Servicios de aplicaciones” se encuentra en el proyecto “Aplicación” en “Core > Application > Interfaces > Services”. En el siguiente ejemplo, estamos demostrando los métodos “Agregar/Actualizar/Eliminar/Obtener/GetAll”.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// Interface: IOrderService.cs
namespace Application.Interfaces.Services;
public interface IOrderService
{
    void Add(Application.Services.Order.Model.Order command);
    void Update(Application.Services.Order.Model.Order command);
    void Delete(Application.Services.Order.Model.Order command);
    Application.Services.Order.Model.Order 
    Get(Application.Services.Order.Model.Order query);
    PagingResult<IList<Application.Services.Order.Model.Order>>
    GetAll(Application.Services.Order.Model.Order query);
}

#3 - Implementación del servicio de aplicaciones OrderService.cs
En la estructura de la plataforma Devprime, la carpeta para la implementación de “Servicios de aplicaciones” en el proyecto de aplicación se encuentra en “Core > Application > Services”. En el siguiente ejemplo, reproducimos un ejemplo de implementación del método “Add” en el que toma el comando y lo convierte en el modelo de dominio. Cuando se usa la instrucción Dp.Attach(order), se agrega el objeto a “Devprime Pipeline” y, a continuación, ejecute el método Add.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// Application Services: OrderService.cs
namespace Application.Services.Order;
public class OrderService : ApplicationService<IOrderState>, IOrderService
{
    public OrderService(IOrderState state, IDp dp) : base(state, dp)
    {
    }
    public void Add(Model.Order command)
    {
        Dp.Pipeline(Execute: () =>
        {
            var order = command.ToDomain();
            Dp.Attach(order);
            order.Add();
        });
    }
    
}

#4 - Implemente los controladores CreateOrderEventHandler.cs y OrderCreatedEventHandler.cs
En la estructura de la plataforma Devprime, para mantener el desacoplamiento, las reglas de negocio no se comunican directamente con las tecnologías. En su lugar, los “Handlers” se implementan en “Core > Application > EventHandlers”, que se utilizan para habilitar el código que reacciona a un hecho empresarial (“Evento de dominio”), por ejemplo, Dp.ProcessEvent<bool>(new CreateOrder()), emitido dentro del dominio.

Ejemplo de implementación del controlador: CreateOrderEventHandler.

El código de ejemplo muestra la persistencia de un agregado en una base de datos mediante la interacción con el adaptador de State. Esta implementación tecnológica en la Aplicación está aislada del Dominio.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// Application Handler: CreateOrderEventHandler
namespace Application.EventHandlers.Order;
public class CreateOrderEventHandler : EventHandler<CreateOrder, IOrderState>
{
    public CreateOrderEventHandler(IOrderState state, IDp dp) : base(state, dp)
    {
    }
    public override dynamic Handle(CreateOrder createOrder)
    {
        var order = createOrder.Get<Domain.Aggregates.Order.Order>();
        return Dp.State.Order.Add(order);
    }
}

Ejemplo de implementación del controlador: OrderCreatedEventHandler.

El código de ejemplo habilita la emisión de un evento al permitir la comunicación de un hecho de negocio externamente al microservicio, a través de la interacción con Stream, que se integra a la perfección con RabbitMQ, Kafka y otras plataformas. Esta implementación tecnológica en la Aplicación está aislada del Dominio.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Application Handler: OrderCreatedEventHandler
namespace Application.EventHandlers.Order;
public class OrderCreatedEventHandler : EventHandler<OrderCreated,
 IOrderState>
{
    public OrderCreatedEventHandler(IOrderState state, IDp dp)
     : base(state, dp)
    {
    }
    public override dynamic Handle(OrderCreated orderCreated)
    {
        var success = false;
        var order = orderCreated.Get<Domain.Aggregates.Order.Order>();
        var destination = Dp.Settings.Default("stream.orderevents");
        var eventName = "OrderCreated";
        var eventData = new OrderCreatedEventDTO()
        {ID = order.ID, CustomerName = order.CustomerName,
        CustomerTaxID = order.CustomerTaxID, Total = order.Total};
        Dp.Stream.Send(destination, eventName, eventData);
        success = true;
        return success;
    }
}

#5 - Implementación de modelos utilizados en controladores de eventos
En la estructura de la plataforma Devprime, la carpeta para la implementación de los “Modelos” para los “EventHandlers” se encuentra en el “Core > Application > EventHandlers > Order > Model” y se utilizan en la comunicación con los Adaptadores.

1
2
3
4
5
6
7
8
9
// Model: CreateOrderEventModel
namespace Application.Services.Order.Model;
public class CreateOrderEventDTO
{
    public Guid ID { get; set; }
    public string CustomerName { get; set; }
    public string CustomerTaxID { get; set; }
    public double Total { get; set; }
}
1
2
3
4
5
6
7
8
9
//Model: OrderCreatedEventDTO
namespace Application.Services.Order.Model;
public class OrderCreatedEventDTO
{
    public Guid ID { get; set; }
    public string CustomerName { get; set; }
    public string CustomerTaxID { get; set; }
    public double Total { get; set; }
}

#6 - Registro de identificadores para eventos de dominio EventHandler.cs
En la capa de Aplicación en “Core / Application / EventHandlers” se dispondrá de un HUB para registrar los Handles que estarán interceptando los eventos del dominio y estableciendo una relación entre ellos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
//HUB: EventHandler
Core > Application > EventHandlers
namespace Application.EventHandlers;
public class EventHandler : IEventHandler
{
    public EventHandler(IHandler handler)
    {
        handler.Add<CreateOrder, CreateOrderEventHandler>();
        handler.Add<OrderCreated, OrderCreatedEventHandler>();
        
    }
}

#7 - Implementación de Inferface IOrderState.cs
La capa de aplicación también desempeña un papel importante en el registro de interfaces para la interacción con otros adaptadores, como State. Las interfaces están organizadas en la estructura de carpetas “Core > Application > Interfaces > Adapters” y, de acuerdo con este contexto, usaremos una carpeta específica para el Adaptador.

1
2
3
4
5
6
//Inferface: IOrderState
namespace Application.Interfaces.Adapters.State;
public interface IOrderState
{
    IOrderRepository Order { get; set; }
}

Orden

Ejemplo de implementación del modelo “Order” para su uso en App Service.

Artículo

Ejemplo de implementación del modelo “Item” para su uso en App Service.

Última modificación April 16, 2024 (2b35fcc8)