C# 不为类型'提供服务;MyType';已注册
我有一个通用的存储库体系结构,如下所示: 存储库C# 不为类型'提供服务;MyType';已注册,c#,.net,dependency-injection,.net-core,asp.net-core-2.0,C#,.net,Dependency Injection,.net Core,Asp.net Core 2.0,我有一个通用的存储库体系结构,如下所示: 存储库 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>
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 interface IUserRepository : IRepository<ApplicationUser>
{
void DoTheThing();
}
public class UserRepository : Repository<ApplicationUser>, IUserRepository
{
public UserRepository(ApplicationDbContext dbContext) : base(dbContext) {}
public void DoTheThing()
{
}
}
公共接口i假设,其中T:class
{
IList Get(Func where);
}
公共抽象类存储库:IRepository,其中T:class
{
私有只读数据库集实体;
受保护的存储库(ApplicationDbContext dbContext)
{
_entity=dbContext.Set();
}
公共IList Get(Func where)
{
返回_entity.Where(Where.ToList();
}
}
然后创建如下具体实现:
UserRepository
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 interface IUserRepository : IRepository<ApplicationUser>
{
void DoTheThing();
}
public class UserRepository : Repository<ApplicationUser>, IUserRepository
{
public UserRepository(ApplicationDbContext dbContext) : base(dbContext) {}
public void DoTheThing()
{
}
}
公共类用户存储库:存储库
{
公共用户存储库(ApplicationDbContext dbContext):基本(dbContext){}
//可以添加IRepository中未包含的任何其他方法
}
我可能会有很多服务,所以我不想让每个服务都单独传递到控制器中,我想我应该尝试传递一个可以为我生成存储库的工厂
存储工厂
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 interface IUserRepository : IRepository<ApplicationUser>
{
void DoTheThing();
}
public class UserRepository : Repository<ApplicationUser>, IUserRepository
{
public UserRepository(ApplicationDbContext dbContext) : base(dbContext) {}
public void DoTheThing()
{
}
}
公共接口IRepositoryFactory
{
T GetRepository(),其中T:class;
}
公共类存储工厂:IRepositoryFactory
{
专用只读服务器ViceProvider(提供程序);
公共存储工厂(IServiceProvider服务提供商)
{
_提供者=服务提供者;
}
public T GetRepository(),其中T:class
{
return _provider.GetRequiredService();//错误:尚未注册“UserRepository”类型的服务
}
}
现在,在设置依赖项注入时,我注册了如下服务:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// [...]
services.AddScoped<IRepository<ApplicationUser>, UserRepository>();
services.AddScoped<IRepositoryFactory, RepositoryFactory>();
// [...]
}
public void配置服务(IServiceCollection服务)
{
// [...]
services.addScope();
services.addScope();
// [...]
}
所有这些都在控制器中使用,如下所示:
控制器
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
}
// [...]
}
公共类HomeController:控制器
{
私有只读用户存储库_UserRepository;
公共家庭控制器(IRepositoryFactory repositoryFactory)
{
_userRepository=repositoryFactory.GetRepository();//错误:尚未注册“userRepository”类型的服务
}
// [...]
}
当我在repositoryFactory.GetRepository()
方法中调用\u provider.GetRequiredService()
时,我在上面的注释中得到了错误
RepositoryFactory
运行正常,但是UserRepository
没有注册。我错过了什么?我尝试在构造函数之外调用GetRepository
方法,并尝试将AddScoped
更改为其他Add
变体(瞬态和单例),但没有效果。您依赖于UserRepository
,这是实现而不是接口,这不好(假设您实际上已在容器中注册了该接口)。相反,您需要依赖接口:IRepository
。因此,请更改您的工厂接口:
public interface IRepositoryFactory
{
IRepository<T> GetRepository<T>() where T : class;
}
公共接口IRepositoryFactory
{
IRepository GetRepository(),其中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 IRepository GetRepository(),其中T:class
{
return _provider.GetRequiredService();//错误:尚未注册“UserRepository”类型的服务
}
和控制器:
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
}
// [...]
}
公共类HomeController:控制器
{
私有只读IRepository用户存储库;
公共家庭控制器(IRepositoryFactory repositoryFactory)
{
_userRepository=repositoryFactory.GetRepository();//错误:尚未注册“userRepository”类型的服务
}
// [...]
}
现在它不起作用了,因为您在容器中注册了
IRepository
(实现是UserRepository
),但是您尝试解析的UserRepository
没有注册(如上所述,您无论如何都不应该解析它).看起来我的问题与我对AddScoped
的理解有关。查看文档,AddScoped
中的两个类型参数是TService
和TImplementation
。因此在我上面的启动类中,我注册的服务是irepositionory
,而不是ApplicationRepository
。我正在注册的实现是ApplicationRepository
为了解决这个问题,我更改了我的Startup
类,说UserRepository
是正在注册的服务
public void ConfigureServices(IServiceCollection services)
{
// [...]
// OLD: services.AddScoped<IRepository<ApplicationUser>, UserRepository>();
services.AddScoped<UserRepository>();
services.AddScoped<IRepositoryFactory, RepositoryFactory>();
// [...]
}
启动
public void ConfigureServices(IServiceCollection services)
{
// [...]
services.AddScoped<IUserRepository, UserRepository>();
services.AddScoped<IRepositoryFactory, RepositoryFactory>();
// [...]
}
public void配置服务(IServiceCollection服务)
{
// [...]
services.addScope();
services.addScope();
// [...]
}
我们都在同一时间输入答案,但我认为我们说的基本上是一样的。这就是解决方案。