使用由 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>
的限制。
我有一个 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>
的限制。