Persistencia de Agregado

68 views
Skip to first unread message

German Valencia

unread,
Sep 11, 2017, 1:53:44 PM9/11/17
to DDD-es

Hola estoy tratando de entender un poco el patron agregado en CSharp  y realice
Necesito realizar algo como esta imagen...


Este codigo como ejemplo..
   public class FacturaEncabezado
   
{
       
public FacturaEncabezado()
       
{
           
FacturaDetalle = new HashSet<FacturaDetalle>();
       
}

       
[Key]
       
// public int IdFacturaEncabezado { get; set; }
       
public Guid IdFacturaEncabezado  { get; private set; }

       
public int? IdCliente { get; set; }

       
[Required]
       
[StringLength(6)]
       
public string NumeroFactura { get; set; }

       
[StringLength(5)]
       
public string CodigoEmpresa { get; set; }

       
[StringLength(85)]
       
public string CodigoCliente { get; set; }

       
public float? sub_total { get; set; }

       
public float? impuesto { get; set; }

       
public float? Total { get; set; }

       
[Column(TypeName = "smalldatetime")]
       
public DateTime? fechaFactura { get; set; }

       
public virtual Cliente Cliente { get; set; }

       
public virtual ICollection<FacturaDetalle> FacturaDetalle { get; set; }

    public void AddFacturaDetalle(int nroFac, string CodProd, float Desc, short Cant,)
   
{

         
FacturaDetalle FacLine = new FacturaDetalle;
         
FacLine.NumeroFactura = nroFac;
         
FacLine.CodigoProducto = CodProd
           
...

   
}


   
}

mi pregunta es como implemento esta Entidad en IRepositoryFactura y RepositoryFactura? Con el patron Repositorio ya que FacturaEncabezado y facturaDetalle las tengo como clases poco y que tienen asociacion en base de datos por public virtual ICollection<FacturaDetalle> FacturaDetalle { get; set; }

Carlos Peix

unread,
Sep 12, 2017, 5:51:07 AM9/12/17
to ddd-es
Hola German,

Yo uso la siguiente regla: un repositorio por cada agregado y el tipo de ese repositorio es el tipo de objeto raiz del agregado (en tu caso, FacturaEncabezado.

Eso contesta tu pregunta?

Hasta ahí llegó mi respuesta en la lista altnet-hispano. En esta lista donde el tópico es DDD, agrego algunas cosillas que me resonaron:
  • Me parece muy bueno el uso del método AddFacturaDetalle de manera que quede dentro de la factura la responsabilidad de crear su detalle y no quede afuera. Por otro lado, permite ocultar detalles de implementación de la colección de detalles. Sin embargo, en el contexto de la factura como está, me suena que ese método podría llamarse AddDetalle en lugar de AddFacturaDetalle.
  • Sugiero que evalúes usar el nombre Factura en Lugar de FacturaEncabezado. El sufijo encabezado podría ser más una cuestión de implementación que algo que tenga sentido para el dominio.
  • Si este es tu modelo de dominio, sugiero evalúes usar la interfaz "fluent" en el evento OnModelCreating (Entity Framework) para indicar las particularidades de persistencia como longitudes, tipos de datos, etc. De esa manera te quedan mejor separados los concerns.
  • Parece haber varias convenciones de nombrado de variables en ese código
  • Me suena raro el campo CodigoCliente en la factura, siendo que tenés la relación con el cliente como una propiedad.
Un abrazo

----------------------------------
Carlos Peix

--
Has recibido este mensaje porque estás suscrito al grupo "DDD-es" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a ddd-es+unsubscribe@googlegroups.com.
Para publicar en este grupo, envía un correo electrónico a ddd...@googlegroups.com.
Visita este grupo en https://groups.google.com/group/ddd-es.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

German Valencia

unread,
Sep 12, 2017, 1:39:33 PM9/12/17
to DDD-es
hola Carlos, pues yo creo repositorios base para crud y para algunas consultas basicas; cuando creo un repositorio especifico es para entidades complejas y como el ejemplo que publique (ah! aclaro estas porciones de codigo son como ejemplo no utilizo esa terminologia en codigo de producción, solo para que se entienda un poco) , como te digo estoy Aprendiendo y mi repositorio especifico de factura lo construiria asi? (colocando el metodo del agregado en el repositorio?)

Introducir código aquí...

   public class FacturaRepository : IFacturaRepository
   
{

       
public void AddLineaFactura()
       
{

          //en este metodo que podria colocar????
           
throw new NotImplementedException();
       
}

       
public void GetFacturaLinea(int? id)
       
{
           
throw new NotImplementedException();
       
}
   
}


Gracias por la ayuda!! si tienes codigo que explique o ejemplo te lo agradeceria

----------------------------------
Carlos Peix

Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a ddd-es+un...@googlegroups.com.

Carlos Peix

unread,
Sep 12, 2017, 6:00:12 PM9/12/17
to ddd-es
German,

Una aclaración adicional que a mi me sirvió para entender aggregates es que el concepto se relaciona con el ciclo de vida de un conjunto de instancias de objetos relacionadas. Son claves los conceptos que marqué en negrita.

Yo no incluyo métodos como GerLineaFactura o AddLineaFactura en el repositorio de un aggregate, nunca. La persistencia de todo el aggregate (en aggregate root y sus instancias relacionadas) es responsabilidad del repositorio, en particular de la configuración del ORM que utilices.

Cuando borras una factura, el ORM debe borrar sus ítems pero no debe borrar el cliente al cual se la emitiste. Esta es la semántica usual en un sistema de facturación (Cliente es un aggregate y Factura con sus ítems es otro aggregate).

Lo mismo para las demás operaciones de persistencia.

De hecho, para las operaciones CRUD suele bastar con un solo repositorio genérico, siempre hablando de una operación de read básica por Id. Escribo código C#, aquí, de memoria:

public class Repository <T> : where T is Entity  // si quisieras restringir a una clase base
{
    public T Get(Guid id) {...}
    public void Create(T entity) {...}
    public T Update(T entity) {...}   // A veces este método no es necesario 
    public void Delete(T entity) {...}
}

Un saludo!

----------------------------------
Carlos Peix

Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a ddd-es+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages