Reputation: 25523
The canonical answer on where to put Database.SetInitializer
calls is in Global.asax
for web projects. I'm looking for another option.
We're using Entity Framework 4.3.1 with Code First. We write web services and WinForms applications, and typically put data access code (such as DbContexts) in shared libraries.
Currently, the constructors of our DbContext descendants look like this:
public PricingContext(string connectionString)
: base(connectionString)
{
Database.SetInitializer<PricingContext>(null);
}
95% of the time, that's the right default. 5% of the time (some integration tests, greenfield development, etc.) it's not.
If we move that code into the initialization (or configuration) of our services and applications, adding a new DbContext to a library involves Shotgun Surgery. All of these projects have to be updated, even if the library doesn't expose the context directly.
Optional arguments are one possibility:
public PricingContext(string connectionString,
IDatabaseInitializer<PricingContext> databaseInitializer = null)
: base(connectionString)
{
Database.SetInitializer<PricingContext>(databaseInitializer);
}
Overriding the default strategy might involve passing the initializer through multiple layers, though.
We've also considered creating a reflection-based initializer that would set all contexts to a specific strategy.
What's the best practice?
Upvotes: 6
Views: 1185
Reputation: 364259
EF 4.3 (and newer) also includes possibility to define initializer from configuration file so you will not need to set it in code at all but it will still require you to maintain multiple configs.
@Hasan's advice looks like the best solution for you.
Upvotes: 2
Reputation: 35126
How about creating a DBContextBootstrapper class that you can instantiate in Global.asax of every project; which in its implementation sets initializer for every context.
This way if you add a new dbcontext you have to make change in the bootstrapper only, not in every project.
Upvotes: 6