Configuração baseada em código
Observação
EF6 em diante apenas: os recursos, as APIs etc. discutidos nessa página foram introduzidos no Entity Framework 6. Se você estiver usando uma versão anterior, algumas ou todas as informações não se aplicarão.
A configuração de um aplicativo do Entity Framework pode ser especificada em um arquivo de configuração (app.config/web.config) ou por meio de código. Este último é conhecido como configuração baseada em código.
A configuração em um arquivo de configuração é descrita em um artigo separado. O arquivo de configuração tem precedência sobre a configuração baseada em código. Em outras palavras, se uma opção de configuração for definida no código e no arquivo de configuração, a configuração no arquivo de configuração será a usada.
Usando DbConfiguration
A configuração baseada em código no EF6 e posterior é obtida com a criação de uma subclasse de System.Data.Entity.Config.DbConfiguration
. As diretrizes a seguir devem ser seguidas ao criar subclasses de DbConfiguration
:
- Crie apenas uma classe
DbConfiguration
para seu aplicativo. Essa classe especifica as configurações de todo o domínio do aplicativo. - Coloque sua classe
DbConfiguration
no mesmo assembly que sua classeDbContext
. (Consulte a seção MovendoDbConfiguration
se você quiser alterar isso). - Dê à sua classe
DbConfiguration
um construtor público sem parâmetros. - Defina as opções de configuração chamando métodos
DbConfiguration
protegidos de dentro desse construtor.
Seguir essas diretrizes permite que o EF descubra e use sua configuração automaticamente por meio de ferramentas que precisam acessar seu modelo e quando seu aplicativo é executado.
Exemplo
Uma classe derivada de DbConfiguration
pode ter esta aparência:
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"));
}
}
}
Essa classe configura o EF para usar a estratégia de execução do SQL Azure – para repetir automaticamente operações de banco de dados com falha – e usar o BD Local para bancos de dados criados por convenção a partir do Code First.
Movendo DbConfiguration
Há casos em que não é possível colocar sua classe DbConfiguration
no mesmo assembly que sua classe DbContext
. Por exemplo, você pode ter duas classes DbContext
cada em assemblies diferentes. Há duas opções para lidar com isso.
A primeira opção é usar o arquivo de configuração para especificar a instância DbConfiguration
a ser usada. Para fazer isso, defina o atributo codeConfigurationType da seção entityFramework. Por exemplo:
<entityFramework codeConfigurationType="MyNamespace.MyDbConfiguration, MyAssembly">
...Your EF config...
</entityFramework>
O valor de codeConfigurationType deve ser o nome qualificado do assembly e do namespace da sua classe DbConfiguration
.
A segunda opção é colocar DbConfigurationTypeAttribute
em sua classe de contexto. Por exemplo:
[DbConfigurationType(typeof(MyDbConfiguration))]
public class MyContextContext : DbContext
{
}
O valor passado para o atributo pode ser o tipo DbConfiguration
, conforme mostrado acima, ou a cadeia de caracteres do nome de tipo qualificado do assembly e namespace. Por exemplo:
[DbConfigurationType("MyNamespace.MyDbConfiguration, MyAssembly")]
public class MyContextContext : DbContext
{
}
Configurando DbConfiguration
explicitamente
Há algumas situações em que a configuração pode ser necessária antes de qualquer tipo DbContext
ser usado. Alguns exemplos disso incluem:
- Usar
DbModelBuilder
para criar um modelo sem um contexto - Usando algum outro código de estrutura/utilitário que utiliza um
DbContext
em que esse contexto é usado antes que o contexto do aplicativo seja usado
Nessas situações, o EF não consegue descobrir a configuração automaticamente e, em vez disso, você deve executar um dos seguintes procedimentos:
- Defina o tipo
DbConfiguration
no arquivo de configuração, conforme descrito na seção MovendoDbConfiguration
acima - Chame o método estático
DbConfiguration
.SetConfiguration durante a inicialização do aplicativo
Substituindo DbConfiguration
Há algumas situações em que você precisa substituir o conjunto de configuração no DbConfiguration
. Isso normalmente não é feito por desenvolvedores de aplicativos, mas sim por provedores e plug-ins de terceiros que não podem usar uma classe DbConfiguration
derivada.
Para isso, o EntityFramework permite que seja registrado um manipulador de eventos que pode modificar a configuração existente pouco antes de ser bloqueado. Ele também fornece um método de açúcar especificamente para substituir qualquer serviço retornado pelo localizador de serviço EF. É assim que se destina a ser usado:
- Na inicialização do aplicativo (antes do EF ser usado), o plug-in ou provedor deve registrar o método do manipulador de eventos para esse evento. (Observe que isso deve acontecer antes que o aplicativo use o EF.)
- O manipulador de eventos faz uma chamada para ReplaceService para cada serviço que precisa ser substituído.
Por exemplo, para substituir IDbConnectionFactory
e DbProviderService
você registraria um manipulador mais ou menos assim:
DbConfiguration.Loaded += (_, a) =>
{
a.ReplaceService<DbProviderServices>((s, k) => new MyProviderServices(s));
a.ReplaceService<IDbConnectionFactory>((s, k) => new MyConnectionFactory(s));
};
No código acima, MyProviderServices
e MyConnectionFactory
representam suas implementações do serviço.
Você também pode adicionar manipuladores de dependência adicionais para obter o mesmo efeito.
Observe que você também pode encapsular DbProviderFactory
dessa forma, mas fazer isso afetará apenas o EF e não os usos do DbProviderFactory
fora do EF. Por essa razão, você provavelmente vai querer continuar a encapsular DbProviderFactory
como fez antes.
Você também deve levar em conta os serviços executados externamente para seu aplicativo, por exemplo, ao executar migrações do Console do Gerenciador de Pacotes. Quando você executar a migração do console, ele tentará localizar seu DbConfiguration
. No entanto, se ele obterá ou não o serviço encapsulado depende de onde o manipulador de eventos foi registrado. Se ele estiver registrado como parte da construção do seu DbConfiguration
, então o código deverá ser executado e o serviço deverá ser encapsulado. Normalmente, não é o que ocorre e isso significa que as ferramentas não receberão o serviço encapsulado.