【问题标题】:How to inject EntityFramework Core DbContext in Repository如何在存储库中注入 EntityFramework Core DbContext
【发布时间】:2017-03-04 23:11:17
【问题描述】:

大多数在线示例都处理 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 应用程序的执行过程中看到这种情况,这通常表明一个注册为 per-HTTP 请求的组件正在被 SingleInstance() 请求

此时我应该手动解析一个新的 DbContext 吗?或者也许我应该改变我的回购的生命周期?

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

【问题讨论】:

  • 您尝试将您的上下文注册为 builder.RegisterType().InstancePerRequest();
  • 为什么不把你的 DbContext 添加到 Startup.cs 中的 ConfigureServices 方法中呢?类似services.AddDbContext&lt;MyContext&gt;(options =&gt; options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); 并在那里添加您的存储库:services.AddScoped&lt;IDealRepository, DealRepository&gt;();
  • 我没有Startup.cs,因为我不在 asp.net 上下文中。这是在 MicrosoftBot 框架应用程序中。我会在最初的问题中澄清。
  • 您可以尝试为 MyContext 注册 InstancePerLifetimeScope() 而不是 InstancePerRequest()
  • @HaHoang 是的,这就是我最初的问题。

标签: c# entity-framework autofac entity-framework-core botframework


【解决方案1】:

我遇到了类似的问题,经过多次反复,以下代码对我有用:

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 模块

 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(); 

    }
}

【讨论】:

    【解决方案2】:

    我错了,这不是 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>
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2021-05-09
        • 2019-08-17
        • 2018-06-20
        • 2017-11-12
        • 2013-11-07
        • 1970-01-01
        • 2018-08-05
        • 1970-01-01
        • 2020-08-01
        相关资源
        最近更新 更多