使用由 EF 处理的 IOptions<T> 设计 class?

Designing a class using IOptions<T> being handled by EF?

我有一个 class 携带一些我存储在数据库中的信息。

class SomeThing
{
  public Guid Id { get; set; }
  public string Name { get; set; }
  public string Info => "extra info";
}

自然而然,最后的属性被EF省略了entity.Ignore(a => a.Info);。现在,我希望可以从 appsettings.json 设置文本 extra info,所以我引入了一个选项提供程序并使用构造函数注入它(在 [=16= 中注册之后) ]). DI 要求我使用参数化构造函数,而 EF 需要无参数构造函数,所以我的 class 变得有点堵塞。

class SomeThing
{
  private IOptions<Config> Config { get; }

  public SomeThing() { }
  
  public SomeThing(IOptions<Config> config)
  { 
    Config = config;
  }

  public Guid Id { get; set; }
  public string Name { get; set; }
  public string Info => Config.Value.Info;
}

现在,笨拙的复杂性让我怀疑我的设计有缺陷。此外,我看不到 EF 应该如何注入选项的值,因为它依赖于无参数构造函数。我考虑过实现空构造函数并以某种方式获取服务,手动获取值,但在我看来这是一个巨大的危险信号。

我应该如何设计这样的 class?

由于 SomeThing 是您数据库的实体定义,我会避免尝试使用 DI 将选项注入。无论如何,我认为它在 EF Core 中不受支持。

如果您真的需要访问 Info 对象,您可以引用一个与 DI 兼容的不同服务,但是直接从您调用访问的任何代码中直接访问它会不会更容易Info 来自 SomeThing

通常 EF 核心用于在数据库中存储数据。

尽管这是一个有问题的设计决策,您应该将这项工作委托给存储库 class。

ThingRepo.GetSomeThing() 获取实体并根据需要填充 Info 属性。然后它可以在构造函数中注入 IOptions<T>

class ThingRepo
{
    private Config _config;
    private DbContext _db;

    public ThingRepo(IOptions<Config> config, DbContext db)
    {
        _db = db;
        _config = config.Value;
    }

    public async Task<Thing> GetSomeThing()
    {
        var thing = await _db.Set<Thing>().FirstAsync();
        thing.Info = _config.Info;
        return thing;
    }
}

这规避了必须在实体构造函数中要求 IOptions<T> 的限制。