Configuration basée sur le code

Remarque

EF6 et versions ultérieures uniquement : Les fonctionnalités, les API, etc. décrites dans cette page ont été introduites dans Entity Framework 6. Si vous utilisez une version antérieure, certaines ou toutes les informations ne s’appliquent pas.

La configuration d’une application Entity Framework peut être spécifiée dans un fichier config (app.config/web.config) ou via du code. C’est ce qu’on appelle la configuration basée sur le code.

La configuration dans un fichier de configuration est décrite dans un article distinct. Le fichier de configuration est prioritaire sur la configuration basée sur le code. En d’autres termes, si une option de configuration est définie à la fois dans le code et dans le fichier config, le paramètre du fichier config est utilisé.

Utilisation de DbConfiguration

La configuration basée sur le code dans EF6 et versions ultérieures est obtenue en créant une sous-classe de System.Data.Entity.Config.DbConfiguration. Les instructions suivantes doivent être suivies lors de la sous-classe de DbConfiguration :

  • Créez une seule classe DbConfiguration pour votre application. Cette classe spécifie les paramètres à l’échelle du domaine d’application.
  • Placez votre classe DbConfiguration dans le même assembly que votre classe DbContext. (Consultez la section Déplacer DbConfiguration si vous souhaitez modifier cette section.)
  • Donnez à votre classe DbConfiguration un constructeur public sans paramètre.
  • Définissez les options de configuration en appelant des méthodes DbConfiguration protégées à partir de ce constructeur.

Suivre ces instructions permet à EF de découvrir et d’utiliser automatiquement votre configuration en utilisant les outils qui doivent accéder à votre modèle et quand votre application est exécutée.

Exemple

Une classe dérivée de DbConfiguration peut ressembler à ceci :

using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.SqlServer;

namespace MyNamespace
{
    public class MyConfiguration : DbConfiguration
    {
        public MyConfiguration()
        {
            SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy());
            SetDefaultConnectionFactory(new LocalDbConnectionFactory("mssqllocaldb"));
        }
    }
}

Cette classe configure EF pour utiliser la stratégie d’exécution SQL Azure pour réessayer automatiquement les opérations de base de données ayant échoué et utiliser la base de données locale pour les bases de données créées par convention à partir de Code First.

Déplacer DbConfiguration

Il existe des cas où il n’est pas possible de placer votre classe DbConfiguration dans le même assembly que votre classe DbContext. Par exemple, vous pouvez avoir deux classes DbContext chacune dans des assemblys différents. Il existe deux options pour gérer ceci.

La première option consiste à utiliser le fichier de configuration pour spécifier l’instance DbConfiguration à utiliser. Pour ce faire, définissez l’attribut codeConfigurationType de la section entityFramework. Par exemple :

<entityFramework codeConfigurationType="MyNamespace.MyDbConfiguration, MyAssembly">
    ...Your EF config...
</entityFramework>

La valeur de codeConfigurationType doit être le nom qualifié d’assembly et d’espace de noms de votre classe DbConfiguration.

La deuxième option consiste à placer DbConfigurationTypeAttribute sur votre classe de contexte. Par exemple :

[DbConfigurationType(typeof(MyDbConfiguration))]
public class MyContextContext : DbContext
{
}

La valeur passée à l’attribut peut être votre type DbConfiguration, comme indiqué ci-dessus, ou la chaîne de nom de type qualifié d’assembly et d’espace de noms. Par exemple :

[DbConfigurationType("MyNamespace.MyDbConfiguration, MyAssembly")]
public class MyContextContext : DbContext
{
}

Définir DbConfiguration de manière explicite

Il existe certaines situations où la configuration peut être nécessaire avant l’utilisation d’un type DbContext. En voici quelques exemples :

  • Utilisation de DbModelBuilder pour générer un modèle sans contexte
  • Utilisation d’un autre code framework/utilitaire qui utilise un DbContext où ce contexte est utilisé avant l’utilisation du contexte de votre application

Dans de telles situations, EF ne parvient pas à découvrir la configuration automatiquement et vous devez effectuer l’une des opérations suivantes :

  • Définissez le type de DbConfiguration dans le fichier config, comme décrit dans la section Déplacer DbConfiguration ci-dessus
  • Appelez la méthode statique DbConfiguration.SetConfiguration au démarrage de l’application

Remplacer DbConfiguration

Il existe certaines situations où vous devez remplacer l’ensemble de configuration dans DbConfiguration. Cela n’est généralement pas effectué par les développeurs d’applications, mais plutôt par des fournisseurs tiers et des plug-ins qui ne peuvent pas utiliser une classe DbConfiguration dérivée.

Pour cela, EntityFramework permet à un gestionnaire d’événements à inscrire de modifier la configuration existante juste avant son verrouillage. Il fournit également une méthode sugar spécifiquement pour remplacer tout service retourné par le localisateur de service EF. Cette méthode est destinée à être utilisée comme ceci :

  • Au démarrage de l’application (avant l’utilisation d’EF), le plug-in ou le fournisseur doit inscrire la méthode de gestionnaire d’événements pour cet événement. (Notez que cela doit se produire avant que l’application utilise EF.)
  • Le gestionnaire d’événements effectue ensuite un appel à ReplaceService pour chaque service qui doit être remplacé.

Par exemple, pour remplacer IDbConnectionFactory et DbProviderService vous devez inscrire un gestionnaire comme suit :

DbConfiguration.Loaded += (_, a) =>
   {
       a.ReplaceService<DbProviderServices>((s, k) => new MyProviderServices(s));
       a.ReplaceService<IDbConnectionFactory>((s, k) => new MyConnectionFactory(s));
   };

Dans le code ci-dessus, MyProviderServices et MyConnectionFactory représentent vos implémentations du service.

Vous pouvez également ajouter des gestionnaires de dépendances supplémentaires pour obtenir le même effet.

Notez que vous pouvez également encapsuler DbProviderFactory de cette façon, mais cela affecte uniquement EF et non les utilisations des DbProviderFactory en dehors d’EF. Pour cette raison, vous voudrez probablement continuer à encapsuler DbProviderFactory comme vous l’avez déjà fait.

Vous devez également garder à l’esprit les services que vous exécutez en externe vers votre application, par exemple lors de l’exécution de migrations à partir de la console du Gestionnaire de package. Lorsque vous exécutez la migration à partir de la console, elle tente de trouver votre DbConfiguration. Toutefois, l’obtention ou non du service encapsulé dépend de l’emplacement où le gestionnaire d’événements qu’il a inscrit. S’il est inscrit dans le cadre de la construction de votre DbConfiguration, le code doit s’exécuter et le service doit être encapsulé. En règle générale, ce n’est pas le cas et cela signifie que les outils n’obtiennent pas le service encapsulé.