2015-06-27 19 views
6

Düzenleyici hizmeti olarak düzenli hizmet alan önbellek hizmeti oluşturmak istiyorum. Daha sonra önbellek anahtarı olmadığında düzenli servisi aramak ve önbelleği güncellemek istiyorum. Benim fikrim düzenli servis ve önbellek servisinde aynı arayüze sahip olmak. Ancak, önbellek hizmeti uygulamasına enjekte etmeye çalıştığımda ve yöntemi uygularken istisna yapıyorum:Kendisine bağlı olarak doğrudan veya dolaylı olarak yazın Basit Enjektör

IUserRepository türü için kayıtlı delege bir istisna attı. Yapılandırma geçersiz. CacheUserRepository türü, doğrudan veya dolaylı olarak kendisine bağlıdır.

Kodum: Ne oluyor

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

RegisterDecorator yöntemini kullanmak için, CacheUserRepository – qujck

cevap

7

şudur:

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; 
    } 
} 

İşte benim kompozisyon kökü:

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" }; 
    } 
}  

İşte benim önbellek deposu bulunuyor Sen CacheUserRepository sınıf kayıtlı hizmet tipi IUserRepository tarafından. Bu, herkesin IUserRepository (GetInstance<IUserRepository>() numaralı telefonu arayarak ya da yapıcı argümanı olarak bir IUserRepository gerektirerek) istediği anlamına gelir; Basit Enjektör bunu yeni bir CacheUserRepository örneği ile sağlayacaktır.

Şimdiye kadar çok iyi, ancak CacheUserRepository'un kendisi IUserRepository'un bir yapıcı argümanını içeriyor. Bu, Basit Enjektörünüzü CacheUserRepository ürününü yeni bir CacheUserRepository örneğiyle sağlamaya yönlendirecektir. Ve elbette bu yeni örnek, yeni bir CacheUserRepository örneğiyle yeniden verilir. Bu, stackoverflow istisnasına neden olacağından, Simple Injector bunu engeller ve gördüğünüz istisnayı atar.

CacheUserRepository, aslında bir dekoratördür. Basit Enjektör, dekoratörler için destek sunar.

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

RegisterDecorator yöntem döngüsel bağımlılık özel bir özen ve Basit Enjektör kuyruğunu kovalamak olmayacağından emin yapacaktır: Bu gibi kayıt görünmelidir nasıl.

+0

kayıt defterine kayıt olmalısınız. Yardım ettiğin için teşekkür ederim. – Emil