我想创建缓存服务,将常规服务作为构造函数参数。然后,当缓存键不存在时,我想调用常规服务并更新缓存。我的想法是在常规服务和缓存服务中有相同的接口(interface)。但是当我尝试注入(inject)缓存服务实现和执行方法时,我得到了异常:
The registered delegate for type IUserRepository threw an exception. The configuration is invalid. The type CacheUserRepository is directly or indirectly depending on itself.
我的代码:
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" };
}
}
这是我的缓存库:
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;
}
}
这是我的组合根:
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);
}
}
最佳答案
发生的事情如下:您注册了 CacheUserRepository
按服务类型分类IUserRepository
.这意味着每次有人请求 IUserRepository
(通过调用 GetInstance<IUserRepository>()
或要求 IUserRepository
作为构造函数参数),Simple Injector 将为它提供一个新的 CacheUserRepository
。实例。
到目前为止一切顺利,但是 CacheUserRepository
本身包含 IUserRepository
的构造函数参数.这将导致 Simple Injector 为您提供 CacheUserRepository
有了新的 CacheUserRepository
实例。当然,这个新实例再次提供了一个新的 CacheUserRepository
实例。由于这会导致 stackoverflow 异常,Simple Injector 会阻止这种情况并抛出您看到的异常。
你的 CacheUserRepository
实际上是一个装饰器。 Simple Injector 支持处理装饰器。您的注册应该是这样的:
container.Register<IUserRepository, UserRepository>();
container.RegisterDecorator<IUserRepository, CacheUserRepository>();
RegisterDecorator
方法特别注意循环依赖,并确保 Simple Injector 不会追尾。
关于c# - 类型直接或间接取决于自身 Simple Injector,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31088075/