Pregunta

En este momento estoy tratando de encontrar una manera de hacer las cosas de manera más inteligente, y en el transcurso de todo esto, lo único que he logrado hacer es usar una botella llena de excedrina en un solo día.

Suponga que tengo una interfaz llamada IRepository como esta.

 public interface IRepository<T>
 {
    T Get(int id);
    void Add(T value);
    void Update(T value);
    void Delete(T value);
    ...
 }

Y supongamos que tengo una implementación como

public class NHibernateRepository<T>
{
    ...
}

Ahora, todo está bien, puedo hacer todas mis operaciones básicas contra el repositorio para admitir toda la funcionalidad CRUD, pero es posible que desee operaciones especializadas, así que supongo que tengo una interfaz como esta:

public interface IUserRepository : IRepository<User>
{
     IList<User> GetUsersByRole(Role role);
}

Y una implementación como esta:

public class UserRepository : NHibernateRepository<User>, IUserRepository
{
    ....
}

Ok, esa es la configuración básica, ahora hay una cosa más que quiero hacer. Quiero tener registros y transacciones y cosas así de manera transparente. Entonces, lo que me gustaría hacer es usar un marco de inyección de dependencias como Castle Windsor o StructureMap para que cuando solicite IRepository, lo envuelva LoggingRepository y TransactionRepository, los cuales implementan IRepository.

Entonces, lo que quiero hacer es algo como esto:

IUserRepository repository = container.Resolve< IUserRepository>();

y hacer que devuelva un repositorio de usuario que está envuelto en los decoradores de Registro y Transacción, pero no puedo pensar en una forma en que esto funcione alguna vez. La única forma en que puedo pensar en hacer que esto funcione es implementando UserRepository de esta manera:

public class UserRepository : DecoratorRepository<T>, IUserRepository
{
    protected IRepository<T> Repository { get; set; }

    public UserRepository(IRepository<T> innerRepository)
    {
        Repository = innerRepository;
    }
}

Esto significaría que usaríamos la Inyección de dependencia para crear un repositorio decorado y pasarlo al constructor del UserRepository y luego usarlo como el repositorio en el que ejecutamos operaciones. Esto funcionaría, pero todavía no creo que sea ideal.

Entonces, mi pregunta es, ¿estoy en lo cierto en que esta es la única forma de hacer esto, o no estoy entendiendo esto correctamente o simplemente me falta algo por completo? Además, si se ha encontrado con este problema anteriormente, ¿cómo lo resolvió?

¿Fue útil?

Solución

Si va a utilizar decoradores , eso suena correcto. Cada decorador tendría un constructor con un argumento de IRepository y llamaría al código de registro o transacción alrededor de las llamadas al repositorio interno que está decorando.

Como una alternativa que podría considerar, pero con la que tengo muy poca experiencia es la Programación Orientada a Aspectos. En ese escenario, aplica atributos a sus clases que indican qué métodos de registro o transacción desea utilizar. En algún momento, esos métodos se entrelazan en su código, esto puede hacerse como un paso de compilación adicional, o en el caso de SpringFramework.net en el momento de la inyección.

Otros consejos

¿No podría tener una clase base abstracta LoggingRepository que manejaría el registro de sus diferentes Obtener, Agregar, Actualizar, Eliminar, hacerlos virtuales y luego heredar de ellos?

Sin embargo, no estoy seguro de qué problema estás tratando de resolver, ya que creo que puedes haber intentado esto. También podría incluir transacciones, aunque lo más probable es que desee hacerlo en su NHibernateRepository.

Este blog parece una solución para tu problema. Básicamente es el mismo diseño, excepto que en lugar de tener un IRepository protegido, lo convierte en privado de solo lectura.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top