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?
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With