2015-06-27 16 views
6

Desidero creare un servizio cache che ottenga un servizio regolare come parametro costruttore. Quindi, quando la chiave cache non esiste, voglio chiamare il servizio regolare e aggiornare la cache. La mia idea è di avere la stessa interfaccia nel servizio regolare e nel servizio cache. Ma quando sto provando ad iniettare l'implementazione del servizio cache e ad eseguire il metodo ottengo un'eccezione:Tipo direttamente o indirettamente dipendente da se stesso Iniettore semplice

Il delegato registrato per il tipo IUserRepository ha emesso un'eccezione. La configurazione non è valida. Il tipo CacheUserRepository dipende direttamente o indirettamente da se stesso.

Il mio codice:

public interface IUserRepository 
{ 
    UserDTO Get(int userId); 
} 

public class UserRepository : IUserRepository 
{ 
    public virtual UserDTO Get(int userId) 
    { 
      return new UserDTO() { Id = 1, Age = 28, Name = "Emil" }; 
    } 
}  

Ecco il mio repository di cache:

public class CacheUserRepository : IUserRepository 
{ 
    private readonly IUserRepository _userRepository; 
    private readonly ICache _cache; 

    public CacheUserRepository(IUserRepository userRepository, ICache cache) 
    { 
      _userRepository = userRepository; 
      _cache = cache; 
    } 

    public DTO.UserDTO Get(int userId) 
    { 
      var userKey = "User_" + userId.ToString(); 

      UserDTO val = _cache.Get<UserDTO>(userKey); 

      if (val != null) 
        return val; 

      UserDTO user = _userRepository.Get(userId); 
      _cache.Add(userKey, user); 

      return user; 
    } 
} 

Ecco la mia radice composizione:

public class ExecutionClass 
{ 
    private readonly Container _container; 

    public ExecutionClass() 
    { 
     _container = new Container(); 

     _container.Register<IUserRepository, CacheUserRepository>(); 
     _container.Register<ICache, Cache>(); 
    } 

    public UserDTO GetUser(int Id) 
    { 
     //throws: The type CacheUserRepository is directly or indirectly depending 
     // on itself. 
     var userRepo = _container.GetInstance<IUserRepository>(); \ 
     return userRepo.Get(Id); 
    } 
} 
+2

È necessario utilizzare il metodo RegisterDecorator per registrare CacheUserRepository – qujck

risposta

7

Quello che sta accadendo è il seguente: è registrato nella classe CacheUserRepository dal suo tipo di servizio IUserRepository. Ciò significa che ogni volta che qualcuno richiede uno IUserRepository (chiamando GetInstance<IUserRepository>() o richiedendo un IUserRepository come argomento del costruttore), Simple Injector fornirà una nuova istanza CacheUserRepository.

Fin qui tutto bene, ma lo stesso CacheUserRepository contiene un argomento costruttore di IUserRepository. Ciò consentirà a Simple Injector di fornire CacheUserRepository con una nuova istanza CacheUserRepository. E naturalmente questa nuova istanza viene nuovamente fornita con una nuova istanza CacheUserRepository. Poiché ciò causerebbe un'eccezione di stackoverflow, Simple Injector impedisce questo e genera l'eccezione che hai visto.

Il tuo CacheUserRepository è in effetti un decoratore. Simple Injector ha il supporto per la gestione dei decoratori. Questo è come la tua registrazione dovrebbe essere simile:

container.Register<IUserRepository, UserRepository>(); 
container.RegisterDecorator<IUserRepository, CacheUserRepository>(); 

Il metodo RegisterDecorator si prende cura speciale della dipendenza ciclica e farà in modo che semplice iniettore non inseguire la sua coda.

+0

Funziona per me. Grazie per l'aiuto. – Emil

Problemi correlati