如何在 Repository 中注入 EntityFramework Core DbContext

4

大多数在线示例涉及asp.net,并将其DbContext注册为启动服务注册表的一部分。

我尝试像这样注册我的DbContext

builder.RegisterType<MyContext>()
    .As<MyContext>()
    .InstancePerLifetimeScope();

builder.RegisterType<DealRepository>()
    .Keyed<IRepository<Deal>>(FiberModule.Key_DoNotSerialize)
    .As<IRepository<Deal>>()
    .SingleInstance();

builder.RegisterType<CardsDialog>()
    .As<IDialog<object>>()
    .InstancePerDependency();

但我遇到了这个错误

类型 'System.Net.Http.WebRequestHandler' 违反了继承安全性规则。派生类型必须匹配基类型的安全可访问性或者比基类型更低的可访问性。

实际上,MessageController.csPost 上创建了一个新范围,这使得问题变得更加复杂。

using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
{
    var dialog = scope.Resolve<IDialog<object>>();

    await Conversation.SendAsync(activity, () => dialog);

}

如何完成注册?

编辑: 如建议的那样,使用InstancePerRequest解决了问题。但是我还有一个每X秒运行一次的Quartz任务,也需要一个存储库。

builder.RegisterType<DealJob>()
    .AsSelf()
    .SingleInstance();

无法解析类型“BargainBot.Repositories.MyContext”,因为无法定位其所属的生命周期范围。此注册公开了以下服务: - BargainBot.Repositories.MyContext 详细信息--->在请求该实例的作用域中,没有标记匹配“AutofacWebRequest”的作用域可见。如果您在执行 Web 应用程序期间看到这个错误,通常表示正在通过 SingleInstance() 请求注册为每个 HTTP 请求的组件。

我应该在这一点上手动解析一个新的DbContext吗?或者我应该更改我的仓库的生命周期?

编辑2:看起来即使删除整个Quartz作业注册,我仍然会收到这个错误。


你尝试将你的上下文注册为builder.RegisterType<MyContext>().InstancePerRequest(); - Ha Hoang
为什么不在 Startup.csConfigureServices 方法中添加你的 DbContext 呢?像这样:services.AddDbContext<MyContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); 然后也在那里添加你的 Repository:services.AddScoped<IDealRepository, DealRepository>(); - kimbaudi
我没有Startup.cs文件,因为我不在asp.net上下文中。这是一个Microsoft Bot Framework应用程序。我会在原问题中澄清。 - martinni39
你可以尝试使用InstancePerLifetimeScope()来替代InstancePerRequest(),针对MyContext。 - Ha Hoang
@HaHoang 是的,那就是我最初的问题。 - martinni39
显示剩余2条评论
3个回答

4

我曾经遇到过类似的问题,经过多次交流之后,以下代码对我有效:

DbContext

 public class SalesDbContext : DbContext
{
    public SalesDbContext(DbContextOptions<SalesDbContext> options) : base(options)
    {
    }

    public DbSet<Domain.Product.Product> Products { get; set; }


    protected override void OnModelCreating(ModelBuilder builder)
    {
        // Configure database attributes
    }



}

代码库

 public class ProductRepository : IProductRepository
{
    private readonly SalesDbContext _db;

    public ProductRepository(SalesDbContext db)
    {
        _db = db;
    }


}

Autofac Module

 public class DefaultModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        // Register Entity Framework
        var dbContextOptionsBuilder = new DbContextOptionsBuilder<SalesDbContext>().UseSqlServer("MyConnectionString");

        builder.RegisterType<SalesDbContext>()
            .WithParameter("options", dbContextOptionsBuilder.Options)
            .InstancePerLifetimeScope(); 

    }
}

1

我对这个问题的看法是错误的,它不是一个IoC和DbContext问题。似乎它是在.NET平台本身中出现的。

https://github.com/dotnet/corefx/issues/9846#issuecomment-274707732

添加重定向就解决了问题。
  <dependentAssembly>
    <assemblyIdentity name="System.ComponentModel.TypeConverter" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.0.0" />
  </dependentAssembly>

0
安装 System.Net.Http 4.3.1 解决了我的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接