TrueWill
TrueWill

Reputation: 25523

Avoiding Shotgun Surgery with Database.SetInitializer

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

Answers (2)

Ladislav Mrnka
Ladislav Mrnka

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

Muhammad Hasan Khan
Muhammad Hasan Khan

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

Related Questions