c# - 类型直接或间接取决于自身 Simple Injector

标签 c# .net dependency-injection simple-injector

我想创建缓存服务,将常规服务作为构造函数参数。然后,当缓存键不存在时,我想调用常规服务并更新缓存。我的想法是在常规服务和缓存服务中有相同的接口(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/

相关文章:

java - 当使用 Spring 构造函数注入(inject)时,bean 是否在构造函数中完全初始化?

c# - 如何从 ServiceProvider 构建 ServiceCollection?

c# - 如何在 xaml 中绑定(bind) tabitem 的 isselected 属性

c# - 我可以随我的产品重新分发 Microsoft T4 引擎吗?

c# - IHttpActionResult 可接受的返回选项

c# - 多个 ContextMenuStrip 的 ToolStripMenuItem

java - 依赖注入(inject)和 JavaFX

c# - MongoDB:具有重写 ID 和属性的子类出现问题

c# - 使用 Flag 属性时的枚举问题

c# - 将 Action 和 Func 结合在一个参数中