2011-01-21 8 views
5

Estoy trabajando en un pequeño proyecto ASP.NET MVC en este momento.
Estoy tratando de implementar Nhibernate para persistir en una base de datos de MS Sql Server. Después de haber pasado largas horas estudiando DDD y otros proyectos encontrados en Internet, he decidido ir al patrón de repositorio. Ahora estoy enfrentando un dilema.
¿Realmente necesito un repositorio cuando uso Nhinbernate?
¿No sería mejor tener una capa de servicio (no tengo una capa de servicio en el momento) que interactúa con Nhinbernate evitando escribir muchas veces algo así:ASP.NET MVC, Nhibernate y repositorios para proyectos pequeños/medianos

public Domain.Reminder GetById(Guid Code) 
{ 
    return (_session.Get<Domain.Reminder>(Code)); 
} 

public Domain.Reminder LoadById(Guid Code) 
{ 
    return (_session.Load<Domain.Reminder>(Code)); 
} 

public bool Save(Domain.Reminder Reminder) 
{ 
    _session.SaveOrUpdate(Reminder); 
    return (true); 
} 

public bool Delete(Domain.Reminder Reminder) 
{ 
    _session.Delete(Reminder); 
    return (true); 
} 

me encontré con un viejo POST de Ayende que está en contra de los repositorios.
Sé que hay un gran debate sobre estos temas y la respuesta es siempre ... depende, pero me parece que con demasiadas capas de abstracciones las cosas se vuelven más complicadas y difíciles de seguir.
¿Estoy equivocado?

+0

Solo una pequeña nota. No hay un proyecto pequeño-mediano, puede ser pequeño por ahora, pero mañana su gerente le preguntará otra característica, y luego otra, y otra, y al final tendrá un gran proyecto con una arquitectura pequeña-mediana . Realmente no me gusta Big Design Up Front, pero a veces necesitas pensar un poco más adelante. – goenning

+0

Estoy de acuerdo con usted por completo pero, en realidad, no puedo ver el beneficio en el uso del repositorio si no fuera por el hecho de que podría no usar nihbernate en el futuro. Está generando mucho trabajo extra que no puedo justificar en este momento. – LeftyX

Respuesta

7

Ayende estaba en contra de escribir un repositorio de la forma en que lo hizo debido a las razones por las que hizo esta pregunta, es un código repetitivo y NH puede manejarlo de todos modos. Él aboga por simplemente llamar a NH directamente como lo haría con un repositorio, y dejar de preocuparse por ello.

Estoy bastante de acuerdo con él. Realmente no hay mucho que ganar, excepto por más trabajo.

+0

Debo confesar que esta es la respuesta que quería escuchar :-) – LeftyX

0

Encontré algunas razones por las que debería usar Repository/DAO/Whatever.

  1. Unit Testing. Nunca intenté burlarme o ponerme un trozo de ISession, pero diría que debería ser MUCHO más complejo que burlar o pegar un Repositorio/Interfaz DAO.
  2. Reutilización del código. Si escribe su consulta directamente en sus Servicios/Controladores terminará duplicándola cuando necesite reutilizar una consulta específica. Si lo tiene envoltorio en un repositorio, simplemente llame a su método.
  3. Single Responsibility Principle. Difundir sus consultas alrededor de sus Controladores le hace romper este principio.
  4. NHibernate Dependency. Ok, esto es difícil de pasar, pero si necesitas cambiar tu ORM, los repositorios lo hacen más fácil (mira, es más fácil, no fácil :)). O incluso cuando necesite cambiar el usuario DataSource de una Base de datos a Microsoft Active Directory, sería más fácil.

Eso es todo, no recuerdo nada más.

+0

Gracias Oenning. No quiero escribir consultas en mis controladores, sino en una capa de servicio. Creo que es un buen lugar para poner algo de lógica comercial también. No estaría en la interfaz de usuario y sería reutilizable si quisiera conectar mi capa de servicio en otro lugar. Dependencia de Nhibernate. Bueno, sí, puedo estar de acuerdo, pero no creo que vaya a suceder pronto y no creo que sea tan diferente de cambiar un repositorio. Gracias de cualquier manera. – LeftyX

+0

1. Si simula repos, está utilizando el patrón de prueba anti "conocido". 2. Nada dice que no puedes crear abstracciones en tu capa de servicio. Esto es completamente falso. 3. No, en absoluto. Vas a llamar al DB en algún lugar. No importa si está en un servicio o llamada de método repo o parte del controlador. Aún el mismo código. El controlador sigue siendo responsable de consultar el db. – jfar

+0

@jfar 1. ¿Cuál es el patrón de prueba "accesorio conocido"? Nunca lo oí. Siempre me burlo de mis repositorios. 2. Si obtuve lo que me dijiste correcto, terminarás con el mismo diseño que un Repositorio pero lo llamarás de otra manera. ¿Tienes algún ejemplo de esto? Me gustaría ver algún código en este caso. 3. El controlador no es responsable de consultar el DB, necesita pedirle a alguien que lo haga. Recibe la solicitud y en función de ella delega tareas a otras clases y elige la siguiente vista. – goenning

4

Use en su lugar un repositorio genérico. Un repositorio por clase puede ser exagerado.

Utilizo un repositorio con Get, Load, Save métodos y varios métodos de coincidencia (uno para Linq y otro para mis consultas de dominio).

El último método acepta una implementación de ICreateCritiera. A continuación se muestra la interfaz y una implementación de la misma.

public interface ICreateCriteria<T> : ICreateCriteria 
{ 
    DetachedCriteria GetCriteria(); 
} 

public class ChallengesAvailableToRound : ICreateCriteria<Challenge> 
{ 
    private readonly Guid _roundId; 

    public ChallengesAvailableToRound(Round round) 
    { 
     _roundId = round.Id; 
    } 

    public DetachedCriteria GetCriteria() 
    { 
     var criteria = DetachedCriteria.For<Challenge>(). 
      CreateAlias("Event", "e"). 
      CreateAlias("e.Rounds", "rounds"). 
      Add(Restrictions.Eq("rounds.Id", _roundId)); 

     return criteria; 
    } 
} 

Esto me permite dividir las consultas en sus propias clases y volver a utilizarlas en todo mi proyecto con facilidad.

+0

Me gusta tu idea, Kenny. Trataré de trabajar en eso. Gracias – LeftyX

+0

Kenny, creo que tu solución es lo suficientemente buena para mí. Gracias. – LeftyX

Cuestiones relacionadas