0

I'm starting a new ASP.NET project, and I'm trying to follow the multi-project approach I've seen mentioned in multiple questions around Stackoverflow.

I've been following this tutorial, but it assumes only one project for your entire solution. Most notably, it recommends modifying your Global.asax file with code to set the database initializer.

Seeing as how my DAL project doesn't have a Global.asax file, what is the correct procedure for seeding the initial EF database?

Community
  • 1
  • 1
Cavyn VonDeylen
  • 4,189
  • 9
  • 37
  • 52

2 Answers2

2

In the Application_Start of the Global.asax:

Database.SetInitializer(new Configuration());
using (var db = new Context())
{
    try
    {
        db.Database.Initialize(false);
    }
    catch (DataException ex)
    {

    }
    catch (Exception ex)
    {
        throw;
    }
}

Where the Context class lives in the DAL:

public class Context : DbContext
{
    public Context() : base("YourDatabaseName") { }
    public DbSet<Employee> Employees { get; set; }

    // ...

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new EmployeeMap()); 

You do the mapping in a dedicated class public class EmployeeMap : EntityTypeConfiguration<Employee>.

Seeding is done in the DAL:

public sealed class Configuration : DropCreateDatabaseAlways<Context>
{
    protected override void Seed(Context context)
    {
        // Do your seeding here
    }
}
Kris van der Mast
  • 16,343
  • 8
  • 39
  • 61
  • Isn't a goal of the 3 tier system that the web project doesn't need a dependency on the DAL though? Only the BLL? – Cavyn VonDeylen Aug 30 '12 at 15:28
  • 1
    Web -> BLL -> DAL where -> rerpresents a reference to the project. When you compile, the web project will say, hey, I need the BLL build because I reference it. When the BLL builds, it will say hey, I need the DAL because I reference it. The end result, all three .dlls will be present in the final web project build. Just because it doesn't have a direct dependency to the DAL does not mean it will not be a component of the final project. The global.asax will still have access to the namespace, etc. – Tommy Aug 30 '12 at 15:31
  • Maybe I'm not understanding correctly or I'm relying on intellisense too much, but I can't access my DAL namespace/project from by Global.asax file without adding the DAL project as a dependency to the Web project. – Cavyn VonDeylen Aug 30 '12 at 15:36
2

I stand corrected in my above comment that you would have access to the DAL by secondary reference. If you are truly wanting to keep from referencing the DAL in your web project, create a Bootstrapper class in your BLL that does the database stuff for you

The examples are pulled from the following blog post: http://weblogs.asp.net/rashid/archive/2009/02/17/use-bootstrapper-in-your-asp-net-mvc-application-and-reduce-code-smell.aspx

Create a bootstrap interface

public interface IBootstrapperTask
{
    void Execute();
}

Create a class that would handle your database configuration

public class InitializeDatabase : IBootstrapperTask
{
    public void Execute()
    {
        Database.SetInitializer(new Configuration());
        using (var db = new Context())
        {
          try
          {
            db.Database.Initialize(false);
          }
          catch (DataException ex)
          {

          }
          catch (Exception ex)
          {
            throw;
          }
        }
      }
       }

Create a static class that will execute the tasks (you can have more than one, registering routes could be moved to a BootstrapperTask)

public static class Bootstrapper
{
    static Bootstrapper()
    {
        ConfigureContainer();
    }

    public static void Run()
    {
        var tasks = ServiceLocator.Current.GetAllInstances<IBootstrapperTask>();

        foreach(var task in tasks)
        {
            task.Execute();
        }
    }

    private static void ConfigureContainer()
    {
        IUnityContainer container = new UnityContainer();

        UnityConfigurationSection configuration = (UnityConfigurationSection) ConfigurationManager.GetSection("unity");
        configuration.Containers.Default.Configure(container);

        ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(container));
    }
}

Finally, your global.asax would have a one liner

protected void Application_Start()
{
    Bootstrapper.Run();
}

There are some web.config things to do as well that you will see in the blog posting. Also, this question can lend some more information on the specifics of disposing, etc. There are more benefits to boostrapping than simply not having to reference a DAL with some excellent posts around the community on why using this pattern is a good thing as well as a few different approaches on implementation.

Community
  • 1
  • 1
Tommy
  • 39,592
  • 10
  • 90
  • 121
  • This is pretty sexy. For any other newbies coming here like me, you can get the Unity dll's from [here](http://msdn.microsoft.com/en-us/library/ff647202). They weren't included with my installation of VS2010. – Cavyn VonDeylen Aug 30 '12 at 16:37