It looks like Entity Framework 5 lends itself a lot better to an Onion Architecture approach to crafting an ASP.NET Solution than some of its prior incarnations which were very three-layers-flavored. In Visual Studio 2012 I made an MVC4 ASP.NET Web API application and Entity Framework was wired up to work by default in the UI project (called MvcApplication in my "Hello World" example) that was made. I made two other projects in addition to the out of the box one (three total). Shall we go over them?
- The first is just called Core and I gave it no references. It holds one class:
using System;
namespace Core
{
public class Person
{
public int PersonId { get; set; }
public string Name { get; set; }
public DateTime Birthday { get; set; }
public Boolean LikesCats { get; set; }
}
}
- The next is called Infrastructure and I gave it a reference to core and a reference to the Entity Framework .dll which was already in the bin folder of MvcApplication as MvcApplication was spun up with an Entity Framework reference. It too holds one class:
using System.Data.Entity;
using Core;
namespace Infrastructure
{
public class PersonContext : DbContext
{
public DbSet<Person> People { get; set; }
}
}
- The last is the MvcApplication project which should probably have a better name such as UserInterface. It is also "the bootstrapper" referencing both Core and Infrastructure.
Alright, here is an example of using Entity Framework from a controller in the UI. Note: No Miller tools (Fluent NHibernate or StructureMap)
using System;
using System.Web.Mvc;
using Core;
using Infrastructure;
namespace MvcApplication.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
using (var db = new PersonContext())
{
var person = new Person()
{
Name = "Tom",
Birthday = new DateTime(1974, 8, 24),
LikesCats = true
};
db.People.Add(person);
db.SaveChanges();
}
return View();
}
}
}
This works! If a Person-related database table does not yet exist it is created. (This is the code first stuff of modern day Entity Framework in action.) A row will be populated to the table regardless of whether or not the table is created first. I did experience some dirtiness in which if I deleted the table that my app could then get hung up trying to recreate it. I'm not sure why. The table gets named People which keeps with the Entity Framework convention of making tables named as the plural form of the objects they hold (in our case Person). EF was smart enough to name the table People instead of Persons. The end of my Web.config file looks like this:
<entityFramework>
<defaultConnectionFactory
type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory,
EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
</entityFramework>
<connectionStrings>
<add name="PersonContext"
connectionString="server=.\JAESCHKE;database=MyData;Integrated
Security=true;" providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
Addendum 2/14/2014: The use of the PersonContext should really be kept in the Infrastructure. The controller should call an interface in the Core which is hydrated with a repository class out of the Infrastructure which holds the mechanics for the PersonContext. Such a wireup may be done with StructureMap.
Hi there. thank you for sharing this valuable information about the onion architecture, I'm at the very first stages of learning the Onion Architecture so it would be really helpful if you can provide the source code so I can play around with it.
ReplyDeleteI really hope you can share it, thanks.
see "Fluffy Nothing" at my GitHub... it's just getting started
DeleteThanks just downloaded and it looks a bit complex for me, but I will get the hang of it. Thank you for sharing.
DeleteYou are welcome! Good luck!
DeleteThis comment has been removed by the author.
ReplyDelete