簡體   English   中英

沒有注冊“ MyType”類型的服務

[英]No service for type 'MyType' has been registered

我有一個通用的存儲庫架構,如下所示:

資料庫

public interface IRepository<T> where T: class
{
    IList<T> Get(Func<T, bool> where);
}

public abstract class Repository<T> : IRepository<T> where T: class
{
    private readonly DbSet<T> _entity;

    protected Repository(ApplicationDbContext dbContext)
    {
        _entity = dbContext.Set<T>();
    }

    public IList<T> Get(Func<T, bool> where)
    {
        return _entity.Where(where).ToList();
    }
}

然后像下面這樣創建具體的實現:

用戶資料庫

public class UserRepository : Repository<ApplicationUser>
{
    public UserRepository(ApplicationDbContext dbContext) : base(dbContext) {}

    // Can add any other methods I want that aren't included in IRepository
}

我可能會提供很多服務,所以我不想將每個服務單獨傳遞給控制器​​,而是想傳遞給可以為我生產存儲庫的單個工廠。

倉庫工廠

public interface IRepositoryFactory
{
    T GetRepository<T>() where T : class;
}

public class RepositoryFactory : IRepositoryFactory
{
    private readonly IServiceProvider _provider;

    public RepositoryFactory(IServiceProvider serviceProvider)
    {
        _provider = serviceProvider;
    }

    public T GetRepository<T>() where T : class
    {
        return _provider.GetRequiredService<T>(); // ERROR: No service for type 'UserRepository' has been registered
    }
}

現在,在設置依賴項注入時,我注冊了以下服務:

啟動文件

public void ConfigureServices(IServiceCollection services)
{
    // [...]

    services.AddScoped<IRepository<ApplicationUser>, UserRepository>();
    services.AddScoped<IRepositoryFactory, RepositoryFactory>();

    // [...]
}

像這樣在控制器中全部使用:

控制者

public class HomeController : Controller
{
    private readonly UserRepository _userRepository;

    public HomeController(IRepositoryFactory repositoryFactory)
    {
        _userRepository = repositoryFactory.GetRepository<UserRepository>(); // ERROR: No service for type 'UserRepository' has been registered
    }

    // [...]
}

當我在repositoryFactory.GetRepository<UserRepository>()方法中調用_provider.GetRequiredService<T>()時,出現上述注釋中的錯誤。

RepositoryFactory可以順利通過,但是UserRepository沒有被注冊。 我想念什么? 我嘗試在構造函數之外調用GetRepository方法,並且嘗試將AddScoped更改為其他Add變體(瞬態和Singleton),但無濟於事。

您正在依賴UserRepository ,它是實現而不是接口,所以不好(假設您實際上已在容器中注冊了該接口)。 相反,您需要依賴於接口: IRepository<ApplicationUser> 因此,更改您的工廠界面:

public interface IRepositoryFactory
{
    IRepository<T> GetRepository<T>() where T : class;
}

實現方式:

public IRepository<T> GetRepository<T>() where T : class
{
    return _provider.GetRequiredService<IRepository<T>>(); // ERROR: No service for type 'UserRepository' has been registered
}

和控制器:

public class HomeController : Controller
{
    private readonly IRepository<ApplicationUser> _userRepository;

    public HomeController(IRepositoryFactory repositoryFactory)
    {
        _userRepository = repositoryFactory.GetRepository<ApplicationUser>(); // ERROR: No service for type 'UserRepository' has been registered
    }

    // [...]
}

現在它不起作用,因為您在容器中注冊了IRepository<ApplicationUser> (實現為UserRepository ),但是您要解析的UserRepository未注冊(如上所述,您無論如何都不應解析)。

看來我的問題與我對AddScoped理解有關。 查看文檔, AddScoped中的兩個類型參數是TServiceTImplementation 因此,在上面的啟動類中,我正在注冊的SERVICEIRepository<ApplicationUser>而不是ApplicationRepository 我注冊的實現ApplicationRepository

為了解決這個問題,我將Startup類更改為說UserRepository是正在注冊的服務。

public void ConfigureServices(IServiceCollection services)
{
    // [...]

    // OLD: services.AddScoped<IRepository<ApplicationUser>, UserRepository>();
    services.AddScoped<UserRepository>();
    services.AddScoped<IRepositoryFactory, RepositoryFactory>();

    // [...]
}

但是這種方法依賴於實現而不是抽象(接口),因此我更進一步,介紹了UserRepository類的接口並將其注冊在Startup

用戶資料庫

public interface IUserRepository : IRepository<ApplicationUser>
{
    void DoTheThing();
}

public class UserRepository : Repository<ApplicationUser>, IUserRepository
{
    public UserRepository(ApplicationDbContext dbContext) : base(dbContext) {}

    public void DoTheThing()
    {

    }
}

啟動

public void ConfigureServices(IServiceCollection services)
{
    // [...]

    services.AddScoped<IUserRepository, UserRepository>();
    services.AddScoped<IRepositoryFactory, RepositoryFactory>();

    // [...]
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM