domain driven design - quickly - DDD: ¿Dónde mantener las interfaces de dominio, la infraestructura?
domain driven design quickly (3)
Eric, estuve fuera por un par, así que perdóname por responder tan tarde. Con respecto a dónde colocar los repositorios, personalmente siempre coloco los repositorios en una capa de infraestructura dedicada (por ejemplo, MyApp.Data.Oracle) pero declaro las interfaces a las que los repositorios deben ajustarse en la capa de dominio.
En mis proyectos, la capa de aplicación tiene que acceder a la capa de dominio e infraestructura porque es responsable de configurar la capa de dominio e infraestructura.
La capa de aplicación es responsable de inyectar la infraestructura adecuada en el dominio. El dominio no sabe a qué infraestructura está hablando, solo sabe cómo llamarlo. Por supuesto, uso contenedores IOC como Structuremap para inyectar las dependencias en el dominio. Una vez más, no declaro que esta es la forma en que DDD recomienda estructurar sus proyectos, es solo la forma en que yo configuro mis aplicaciones. Aclamaciones.
¿Tiene sentido agrupar todas las interfaces de su capa de dominio (módulos, modelos, entidades, servicios de dominio, etc.) dentro de la capa de infraestructura? Si no es así, ¿tiene sentido crear un proyecto / componente "compartido" que agrupe todos estos en una biblioteca compartida? Después de todo, la definición de "Capa de infraestructura" incluye "bibliotecas compartidas para las capas de Dominio, Aplicación y UI".
Estoy pensando en diseñar mi código base alrededor de las capas DDD: UI, Aplicación, Dominio, Infraestructura. Esto crearía 4 proyectos con respeto. Mi punto es que hace referencia a la capa de infraestructura desde la capa de dominio. Pero si define las interfaces en el proyecto de capa de dominio, por ejemplo, para IPost, entonces tendrá una referencia circulur cuando tenga que hacer referencia al proyecto de capa de dominio del proyecto de infraestructura cuando esté definiendo el método IPostRepository.Save (publicación de IPost) . Por lo tanto, la idea de "definir todas las interfaces en la biblioteca compartida".
Quizás los repositorios no deberían esperar que un objeto se guarde (IPostRepository.Save (publicación de IPost); en cambio, espere los parámetros del objeto (que podría ser un largo conjunto de parámetros en Guardar (), sin embargo). Dado, esto podría ser una situación ideal que muestra cuando un objeto se está volviendo demasiado complejo, y los Objetos de Valor adicionales deben ser investigados para ello.
¿Pensamientos?
Estoy tranquilo en DDD, así que no dude en comentar si no está de acuerdo, ya que estoy aquí para aprender.
Personalmente no entiendo por qué debería hacer referencia a la capa de infraestructura desde su dominio. En mi opinión, el dominio no debería depender de la infraestructura. Los objetos del dominio deben ser completamente ignorantes en la base de datos en la que se ejecutan o en qué tipo de servidor de correo se utiliza para enviar correos. Al abstraer el dominio de la infraestructura es más fácil reutilizarlo; Porque el dominio no sabe en qué infraestructura se está ejecutando.
Lo que hago en mi código es hacer referencia a la capa de dominio desde mi capa de infraestructura (pero no a la inversa). Los repositorios conocen los objetos del dominio porque su función es preservar el estado del dominio. Mis repositorios contienen mis operaciones CRUD básicas para mis agregados de raíz (get (id), getall (), save (object), delete (object) y se llaman desde mis controladores.
Lo que hice en mi último proyecto (mi enfoque no es puramente DDD pero funcionó bastante bien) es que abstraí mis repositorios con interfaces. Los agregados de raíz debían crearse instancias pasando un tipo concreto de un Repositorio:
El agregado raíz se tuvo que crear una instancia a través de un repositorio mediante el uso de Get (ID) o un método Create () del repositorio. El Repositorio concreto que construye el objeto se pasa a sí mismo para que el agregado pueda preservar su estado y el estado de sus objetos secundarios pero sin saber nada de la implementación concreta del repositorio. p.ej:
public class PostRepository:IPostRepository
{
...
public Post Create()
{
Post post=new Post(this);
dbContext.PostTable.Insert(post);
return post;
}
public Save(post)
{
Post exitingPost=GetPost(post.ID);
existingPost = post;
dbContext.SubmitChanges();
}
}
public class Post
{
private IPostRepository _repository
internal Post(IPostRepository repository)
{
_repository = repository;
}
...
Public Save()
{
_repository.Save(this);
}
}
Te aconsejo que consideres la arquitectura de cebolla . Encaja muy bien con DDD. La idea es que las interfaces de su repositorio se encuentren en una capa justo fuera de las entidades de dominio y de referencia directamente:
IPostRepository.Save(Post post)
El dominio no necesita saber acerca de los repositorios en absoluto.
El dominio, o cualquier otra persona, no hace referencia a la capa de infraestructura y contiene implementaciones concretas de repositorios entre otras cosas relacionadas con la E / S. La biblioteca común con varios ayudantes se llama Application Core en este caso, y cualquiera puede hacer referencia a ella.