ASP.NET Core 2 无法解析 Microsoft EntityFrameworkCore DbContext 类型的服务
Posted
技术标签:
【中文标题】ASP.NET Core 2 无法解析 Microsoft EntityFrameworkCore DbContext 类型的服务【英文标题】:ASP.NET Core 2 Unable to resolve service for type Microsoft EntityFrameworkCore DbContext 【发布时间】:2017-09-20 10:56:15 【问题描述】:当我运行我的 asp.net core 2 项目时,我收到以下错误消息:
InvalidOperationException:尝试激活“ContosoUniversity.Service.Class.StudentService”时无法解析“Microsoft.EntityFrameworkCore.DbContext”类型的服务。
这是我的项目结构:
-- solution 'ContosoUniversity'
----- ContosoUniversity
----- ContosoUniversity.Model
----- ContosoUniversity.Service
IEntityService(相关代码):
public interface IEntityService<T> : IService
where T : BaseEntity
Task<List<T>> GetAllAsync();
IEntityService(相关代码):
public abstract class EntityService<T> : IEntityService<T> where T : BaseEntity
protected DbContext _context;
protected DbSet<T> _dbset;
public EntityService(DbContext context)
_context = context;
_dbset = _context.Set<T>();
public async virtual Task<List<T>> GetAllAsync()
return await _dbset.ToListAsync<T>();
实体:
public abstract class BaseEntity
public abstract class Entity<T> : BaseEntity, IEntity<T>
public virtual T Id get; set;
学生服务:
public interface IStudentService : IEntityService<Student>
Task<Student> GetById(int Id);
学生服务:
public class StudentService : EntityService<Student>, IStudentService
DbContext _context;
public StudentService(DbContext context)
: base(context)
_context = context;
_dbset = _context.Set<Student>();
public async Task<Student> GetById(int Id)
return await _dbset.FirstOrDefaultAsync(x => x.Id == Id);
SchoolContext:
public class SchoolContext : DbContext
public SchoolContext(DbContextOptions<SchoolContext> options) : base(options)
public DbSet<Course> Courses get; set;
public DbSet<Enrollment> Enrollments get; set;
public DbSet<Student> Students get; set;
最后是我的 Startup.cs 类:
public class Startup
public Startup(IConfiguration configuration, IHostingEnvironment env, IServiceProvider serviceProvider)
Configuration = configuration;
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.env.EnvironmentName.json", optional: true);
Configuration = builder.Build();
public IConfiguration Configuration get;
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
services.AddDbContext<SchoolContext>(option =>
option.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddScoped<IStudentService, StudentService>();
services.AddMvc();
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
else
app.UseExceptionHandler("/Home/Error");
app.UseStaticFiles();
app.UseMvc(routes =>
routes.MapRoute(
name: "default",
template: "controller=Home/action=Index/id?");
);
我应该怎么做才能解决这个问题?
【问题讨论】:
AddDbContext<SchoolContext>
仅注册您的特定 DbContext SchoolContext
,而不是其基类。尝试搜索。
【参考方案1】:
StudentService
期望 DbContext
但容器不知道如何根据您当前的启动来解决它。
您需要将上下文显式添加到服务集合中
启动
services.AddScoped<DbContext, SchoolContext>();
services.AddScoped<IStudentService, StudentService>();
或者更新StudentService
构造函数以明确期望容器知道如何解析的类型。
学生服务
public StudentService(SchoolContext context)
: base(context)
//...
【讨论】:
请问如果我有multiple dbcontexts
SchoolContext
和TrainingContext
,请问如何使用这个services.AddScoped<DbContext, SchoolContext>();
?
@AnynameDonotcare 您需要区分抽象或更新工厂委托以显式解析目标服务所需的上下文。【参考方案2】:
我遇到了类似的错误,即
处理请求时发生未处理的异常。 InvalidOperationException:尝试激活“MyProjectName.Controllers.MyUsersController”时无法解析“MyProjectName.Models.myDatabaseContext”类型的服务。
Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, bool isDefaultParameterRequired)
后来我发现...我错过了以下行,即将我的数据库上下文添加到服务:
services.AddDbContext<yourDbContext>(option => option.UseSqlServer("Server=Your-Server-Name\\SQLExpress;Database=yourDatabaseName;Trusted_Connection=True;"));
下面是我在 Startup 类中定义的 ConfigureServices 方法:
public class Startup
public Startup(IConfiguration configuration)
Configuration = configuration;
public IConfiguration Configuration get;
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
services.Configure<CookiePolicyOptions>(options =>
// This lambda determines whether user consent for non-essential
//cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddDbContext<yourDbContext>(option =>
option.UseSqlServer("Server=Your-Server-Name\\SQLExpress;Database=yourDatabaseName;Trusted_Connection=True;"));
...
...
基本上,当您从数据库生成模型类时,通过创建“新脚手架项目”并在脚手架过程中选择适当的数据库上下文,将所有数据库表映射到相应的模型类。
现在,您需要手动将您的数据库上下文注册为services
方法的services
参数的服务。
顺便说一句,您最好从配置数据中获取连接字符串,而不是硬编码连接字符串。我试图在这里保持简单。
【讨论】:
【参考方案3】:如果 dbcontext 继承自 system.data.entity.DbContext 那么它会像这样添加
services.AddScoped(provider => new CDRContext());
services.AddTransient<IUnitOfWork, UnitOfWorker>();
services.AddTransient<ICallService, CallService>();
【讨论】:
【参考方案4】:当 options 参数为 null 或无法使用 GetConnectionString() 检索时,将引发此错误。
我遇到此错误是因为定义 ConnectionStrings 的 appsettings.json 文件末尾有一个额外的大括号 。
愚蠢,但令人沮丧。
【讨论】:
以上是关于ASP.NET Core 2 无法解析 Microsoft EntityFrameworkCore DbContext 类型的服务的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Core Web API InvalidOperationException:无法解析服务 [重复]
ASP.NET Core Web API:尝试激活时无法解析服务类型
ASP.NET Core 依赖注入错误:尝试激活时无法解析服务类型 - 调用视图组件时出现错误 [重复]
ASP.NET Core 3:无法从根提供程序解析范围服务“Microsoft.AspNetCore.Identity.UserManager`1[Alpha.Models.Identity.User