Asp.netコア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; }
}
IStudentService:
public interface IStudentService : IEntityService<Student>
{
Task<Student> GetById(int Id);
}
StudentService:
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?}");
});
}
}
この問題を解決するにはどうすればよいですか?
StudentService
はDbContext
を想定していますが、コンテナーは現在のスタートアップに基づいて解決する方法を認識していません。
サービスコレクションにコンテキストを明示的に追加する必要があります
スタートアップ
services.AddScoped<DbContext, SchoolContext>();
services.AddScoped<IStudentService, StudentService>();
OrStudentService
コンストラクターを更新して、コンテナーが解決方法を知っているタイプを明示的に期待します。
StudentService
public StudentService(SchoolContext context)
: base(context)
{
//...
}
同様のエラーが発生しました。
リクエストの処理中に未処理の例外が発生しました。 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
メソッドのConfigureServices
パラメータに手動で登録する必要があります。
ところで、接続文字列をハードコーディングするのではなく、構成データから選択するのが理想的です。ここでは物事をシンプルにするように努めました。
dbcontextがsystem.data.entity .DbContextから継承された場合、そのように追加されます
services.AddScoped(provider => new CDRContext());
services.AddTransient<IUnitOfWork, UnitOfWorker>();
services.AddTransient<ICallService, CallService>();