-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Nate McMaster
committed
Feb 29, 2016
1 parent
a76472e
commit 1411d06
Showing
5 changed files
with
151 additions
and
228 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
* text=auto |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,146 @@ | ||
.. include:: /_shared/stub-topic.txt | ||
Understanding EF Services | ||
========================= | ||
|
||
|stub-icon| Understanding EF Services | ||
===================================== | ||
.. contents:: `In this article` | ||
:local: | ||
:depth: 1 | ||
|
||
.. include:: /_shared/stub-notice.txt | ||
Entity Framework executes as a collection of services working together. A | ||
service is a reusable component. A service is typically an | ||
implementation of an interface. Services are available to other services via | ||
`dependency injection (DI) <https://wikipedia.org/wiki/Dependency_injection>`_, | ||
which is implemented in EF using `Microsoft.Extensions.DependencyInjection | ||
<https://docs.asp.net/en/latest/fundamentals/dependency-injection.html>`_. | ||
|
||
This article covers some fundamentals principles for understanding how EF uses | ||
services and DI. | ||
|
||
Categories of Services | ||
---------------------- | ||
|
||
Services fall into one or more categories. | ||
|
||
Context services | ||
Services that are related to a specific instance of ``DbContext``. They | ||
provide functionality for working with the user model and context options. | ||
|
||
Provider services | ||
Provider-specific implementations of services. For example, SQLite uses | ||
"provider services" to customize the behavior of SQL generation, migrations, | ||
and file I/O. | ||
|
||
Design-time services | ||
Services used when a developer is creating an application. For example, EF | ||
commands uses design-time services to execute migrations and code generation | ||
(aka scaffolding). | ||
|
||
User services | ||
A user can define custom services to interact with EF. These are written in | ||
application code, not provider code. For example, users can provide an | ||
implementation of ``IModelCustomizer`` for controlling how a model is created. | ||
|
||
|
||
Services Initialization | ||
----------------------- | ||
|
||
In order to be used by EF, all services must be registered in a service | ||
collection before or during ``DbContext`` initialization. Registration is done | ||
by adding components to into the ``ServiceCollection`` that EF will eventually | ||
use to create the final ``ServiceProvider``. By the time initialization is | ||
complete, ``DbContext`` has an instance of ``ServiceProvider`` that includes the | ||
collection of provider services, context services, and user services necessary | ||
for operation. | ||
|
||
.. note:: | ||
``ServiceProvider`` is not to be confused with a "provider's services". | ||
|
||
.. _services-initialization: | ||
|
||
Initialization Steps | ||
^^^^^^^^^^^^^^^^^^^^ | ||
|
||
EF will initialize services in the following order. Services registered later | ||
can override or remove previously registered services. | ||
|
||
1. ``DbContext`` obtains an initial set of services. This initial set can be | ||
internal or external. An external set must be found in order to use *user* | ||
and *design-time services*. The initial set is discovered using these steps: | ||
a. An **external** ``ServiceProvider`` can be passed in as a constructor | ||
parameter. | ||
b. If no constructor parameter is defined *and* ``DbContext`` is resolved from | ||
a service provider (i.e. the context was registered with | ||
``AddDbContext<T>()``), then ``DbContextActivator`` will use the | ||
**external** service provider from which the context was resolved. | ||
c. If no external services can be found, ``DbContext`` creates an empty | ||
**internal** ``ServiceProvider`` and calls ``.AddEntityFramework()`` to | ||
add essential services. | ||
2. ``DbContext`` obtains an initial set of options. See also :doc:`/miscellaneous/configuring-dbcontext`. | ||
a. Options can be provided as a constructor parameter.. | ||
b. If no constructor parameter is specified, DbContext will extract any | ||
``DbContextOptions`` relevant to the current DbContext type from | ||
the initial service provider. These options are normally added to the | ||
initial service provider with a call to ``.AddDbContext<T>()``. | ||
c. If no options are in the service provider or given as a constructor parameter, | ||
EF creates an empty set of options. | ||
3. Finalize options by calling ``DbContext.OnConfiguring()``, passing in the initial | ||
options found in step 2. This can overwrite the initial set of options. | ||
4. Add all *provider services* given in the provider-specific implementation of | ||
``IDatabaseProvider.GetProviderServices()``. This is typically found from the | ||
provider specific options extension (``IDbContextOptionsExtension``) which is | ||
added to options when the user calls the "UseProvider()" extension method. | ||
See :doc:`writing-a-provider` for more details. | ||
5. Create a service scope. Any services with scoped `service lifetime`_ will | ||
only operate within this scope. | ||
6. Initialize *context services* from this service scope. | ||
7. As configured in options, select one and only one set of *provider services* | ||
from ``IDatabaseServices``. | ||
|
||
Together, the scoped service provider from step 5, the context services from | ||
step 6, and the selected provider services from step 7 are the final set of | ||
services used by EF. | ||
|
||
|
||
Service Lifetime | ||
---------------- | ||
|
||
EF services can be registered with different lifetime options. The suitable | ||
option depends on how the service is used and implemented. | ||
|
||
Transient | ||
Transient lifetime services are created each time they are injected into other | ||
services. This isolates each instance of the service. For example, | ||
``MigrationsScaffolder`` should not be reused, therefore it is registered as | ||
transient. | ||
|
||
Scoped | ||
Scoped lifetime services are created once per ``DbContext`` instance. This is | ||
used to isolate instance of ``DbContext``. For example, ``StateManager`` | ||
is added as scoped because it should only track entity states for one context. | ||
|
||
Singleton | ||
Singleton lifetime services exists once per service provider and span all | ||
scopes. Each time the service is injected, the same instance is used. For | ||
example, ``IModelCustomizer`` is a singleton because it is idempotent, meaning | ||
each call to ``IModelCustomizer.Customize()`` does not change the customizer. | ||
|
||
Required Provider Services | ||
-------------------------- | ||
|
||
EF providers must register a basic set of services. These required services are | ||
defined as properties on ``IDatabaseProviderServices``. Provider writers may | ||
need to implement some services from scratch. Others have partial or complete | ||
implementations in EF's library that can be reused. | ||
|
||
For more information on required provider services, see :doc:`writing-a-provider`. | ||
|
||
Additional Information | ||
---------------------- | ||
|
||
EF uses `Microsoft.Extensions.DependencyInjection | ||
<https://www.nuget.org/packages/Microsoft.Extensions.DependencyInjection/>`_ to | ||
implement DI. Documentation for this library `is available on docs.asp.net | ||
<https://docs.asp.net/en/latest/fundamentals/dependency-injection.html>`_. | ||
|
||
`"System.IServiceProvider" | ||
<http://dotnet.github.io/api/System.IServiceProvider.html>`_ is defined in the | ||
.NET base class library. |
Oops, something went wrong.