Pergunta

Agora eu estou tentando descobrir uma maneira de fazer as coisas de forma mais inteligente, e no curso de fazê-lo tudo que eu consegui fazer é usar uma garrafa cheia de Excedrin em um único dia.

Suponha que eu tenho uma interface chamada IRepository assim.

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

E supor que eu tenho uma implementação como

public class NHibernateRepository<T>
{
    ...
}

Agora, tudo está bem e bom, eu posso fazer todas as minhas operações básicas contra o repositório para suportar todas as funcionalidades CRUD, mas eu pode querer operações especializadas, por isso supor que eu tenho uma interface como este:

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

E uma implementação como tal:

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

Ok, de modo que é a configuração básica, agora há mais uma coisa que eu quero fazer. Quero ter registro e transação e coisas assim tudo transparente. Então o que eu gostaria de fazer é usar um quadro de injeção de dependência, como o Castelo de Windsor ou StructureMap de modo que quando eu pedir IRepository, eu vou buscá-la envolta por um LoggingRepository e uma TransactionRepository, ambos os quais implementar IRepository.

Então, o que eu quero fazer é algo como isto:

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

e tê-lo retornar um repositório do usuário que está envolto em Log e Transação decoradores, mas eu não posso pensar de uma maneira que este nunca vai trabalho. A única maneira que eu posso pensar de começar este trabalho é através da implementação de UserRepository como tal:

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

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

Isto significaria que iríamos usar Dependência Injection para criar um repositório decorados e passar isso para o construtor da UserRepository e depois usar isso como o repositório em que corremos operações contra. Isso poderia funcionar, mas eu ainda não acho que é ideal.

Então, minha pergunta é, estou certo de que esta é a única maneira de fazer isso, ou eu sou não entender isso corretamente ou apenas faltando alguma coisa todos juntos. Além disso, se você tiver executado contra este problema antes, como você resolver este problema?

Foi útil?

Solução

Se você estiver indo para usar decoradores que soa sobre a direita. Cada decorador teria um construtor com um argumento de IRepository e chamar o código de registro ou transação em torno de chamadas para o repositório interno que está decorando.

Como alternativa, você pode considerar, mas que eu tenho muito pouca experiência com está Aspect Oriented Programming. Nesse cenário, você aplicar atributos para as classes que indicam o que madeireiras ou transação métodos que você deseja usar. Em algum momento, esses métodos se tecida em seu código, isso pode ser feito tanto como como um passo de compilação extra, ou, no caso do SpringFramework.net no momento da injeção.

Outras dicas

Você não poderia ter uma classe base abstrata LoggingRepository que iria lidar com o registo para o seu obter diferentes, adicionar, actualizar, apagar, torná-los virtual e, em seguida, herdam-los?

Eu não tenho certeza que o problema que você está tentando resolver embora como eu acho que você pode ter tentado isso? Você poderia envolver em transações também, embora mais provável que você iria querer fazer isso em sua NHibernateRepository.

Este blog olhares como uma solução para seu problema. É basicamente o mesmo desenho, exceto em vez de ter um IRepository protegido você torná-lo privado somente leitura.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top