英文:
Action<OptionsBuilder> vs Action<Options> pattern?
问题
这两者有何区别?
实际上,Action<Options>
可视为对 Options
的建造者。提供程序可以为 Options
类型提供扩展方法,以隐藏复杂性。
为什么 DbContext
配置使用 Action<DbContextOptionsBuilder>
?
英文:
What are the differences between these?
Actually, Action<Options>
can be treated as a builder to the Options
. And providers can provide extension methods for Options
type to hide the complexity.
Why DbContext
configuration uses Action<DbContextOptionsBuilder>
?
答案1
得分: 1
在IServiceCollection.AddDbContext<TContext>(Action<DbContextOptionsBuilder>? optionsAction)
中,optionsAction
可以改为Action<DbContextOptions>
。
然而,Entity Framework Core的“配置操作”(缺乏更好的术语,这不是“选项模式”)要比普通的依赖注入配置方法复杂得多。
通常情况下,您不仅需要设置一两个字符串(如身份验证cookie),还可能需要一个操作或转换器(比如JSON),但Entity Framework Core存在着非常复杂的配置场景。
因此,正如在 DbContextOptionsBuilder
类的文档中所记录的那样,它:
提供了一个简单的API界面,用于配置DbContextOptions。数据库(和其他扩展)通常在该对象上定义扩展方法,允许您配置要用于上下文的数据库连接(和其他选项)。
它将所有与可扩展性相关的底层细节隐藏在构建器内部,而不是在DbContextOptions
本身上。构建器的细节仅在构建时需要,而一旦构建完成,选项本身在运行时使用。
另请参阅 MS Learn: DbContext 配置和初始化: DbContextOptions:
这些 Use* 方法是由数据库提供程序实现的扩展方法。这意味着必须在使用扩展方法之前安装数据库提供程序 NuGet 包。
以及:
针对数据库提供程序的可选配置是在附加的特定于提供程序的构建器中执行的。例如,使用
EnableRetryOnFailure
配置在连接到 Azure SQL 时的连接弹性重试。
在 Use*
方法中发生的所有操作都用于“构建 DbContextOptions”。您不希望自己完成这些操作,也不希望有一个包含与其设置相关的太多底层细节的 Options 类,这些细节在构建后不再使用。
英文:
You're right in that the optionsAction
in
IServiceCollection.AddDbContext<TContext>(Action<DbContextOptionsBuilder>? optionsAction)
could be an Action<DbContextOptions>
instead.
However, the "configuration action" (by lack of a better term, this is not the "options pattern") of Entity Framework Core is vastly more complex than your average Dependency Injection configuration method.
You're usually not done with setting a string or two (as with authentication cookies) and perhaps an action or a converter (JSON comes to mind), but there are thoroughly complex configuration scenarios for Entity Framework Core.
Therefore, as is documented in the DbContextOptionsBuilder
class, it:
> Provides a simple API surface for configuring DbContextOptions. Databases (and other extensions) typically define extension methods on this object that allow you to configure the database connection (and other options) to be used for a context.
It hides all of the plumbing required for that extensibility inside the builder, as opposed to on the DbContextOptions
itself. The builder plumbing is only required at construction time, while the options themself, once built, are used at runtime.
See also MS Learn: DbContext configuration and initialization: DbContextOptions:
> These Use* methods are extension methods implemented by the database provider. This means that the database provider NuGet package must be installed before the extension method can be used.
And:
> Optional configuration specific to the database provider is performed in an additional provider-specific builder. For example, using EnableRetryOnFailure to configure retries for connection resiliency when connecting to Azure SQL
Everything that happens in the Use*
methods is used to construct a DbContextOptions. You wouldn't want to do that yourself, and you wouldn't want to have an Options class that contains too much plumbing only related to its setup, not to be used after construction.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论