Thursday, March 10, 2011

Another Entity Framework 4 Repository & Unit of Work Solution–Intro and Part 1: Setup

Entity Framework Code First (EF Code First) has been getting quite a bit of press lately.  I’ve done some ‘play’ development using EF Code First; however, the powers that be seem to keep bringing me back to the Model First (create database/ERD and then the application code) paradigm.

What I really like about EF Code First is the seamless use of Separation of Concerns.  My next few posts are going to be a series of entries on using the Model First approach to take advantage of Separation of Concerns.

Rather than discuss software development and design theory, these posts will walk through the process of implementing a solution that separates concerns into specific behaviors using the Entity Framework 4 and the Repository and Unit of Work Patterns.  To facilitate this process, we will be using T4 templates.

While there are many solutions online that create similar implementations, this series will focus on a process that I really like, fits my needs, and is easy to understand.  That last point is important – ‘easy to understand.’  Separation of Concerns and all the concepts that come along with it can be very overwhelming if you’re coming from ASP.NET Web Forms…

Forewarning – this series of posts contain quite a few steps.  I considered creating a NuGet package; however, I couldn’t settle on the structure of the package and I realized that I started losing focus on the intent of my madness.  I also considered creating a few Visual Studio templates; however, my experience with VS templates is limited, and once again the madness had me losing focus.  That said, hopefully this series and the steps involved will not be too overwhelming.  I feel the value of the final results far exceed the steps involved in getting there… 

UPDATE: the NuGet team is considering adding functionality where NuGet could be run from PowerShell outside of Visual Studio. This means that one could create a NuGet package that would create a solution with x number of projects and add dependencies to those projects, files, etc…  If that functionality was available now, I could deploy all the steps involved here in a single NuGet package – eliminating MOST of the steps on this series.  If this sounds cool – it is cool – vote for this functionality here.

Okay, so here is the series breakdown:
Lets get started…

Part 1: Setup

As stated above, in Part 1 we are going to create a database, create a Visual Studio solution and project structure, and generate an EF4 data model that points to our database.

1) Create a database

For this series, we are going to use the Chinook database.  Specifically, we are going to use the Chinook version 1.2 for SQL Server.  You can download the Chinook database from CodePlex – make sure you download version 1.2 – in preparing for this series, I had issues generating EF4 Navigation Properties with Chinook version 1.3, so please use version 1.2. The download contains two SQL scripts for generating the Chinook database.  Please use the SQL Script that generates table primary keys with IDENTITY. Once the Chinook database is generated, the database should similar to the following screenshot from SQL Server Management Studio (SSMS): ChinookSsms

2) Visual Studio Solution and Project Structure

The solution and related projects architecture that we are going to use loosely follows the Onion Architecture Pattern – this is a great read and well worth the time…
  1. Create an empty Visual Studio Solution.
    • Open Visual Studio
    • Click ‘File’ –> ‘New’ –> ‘Project’
    • Under the ‘Installed Templates,’ select the ‘Other Project Types’ node in the project tree, select the ‘Visual Studio Solutions’ node, and then select the ‘Blank Solution.’  Name the solution ‘Chinook.’  Here’s a screenshot of the New Project Wizard:
      solutionwizard
  2. Create the following three Class Library Projects.  Delete the auto-generated ‘Class1.cs’ file that was added to each project.
    • Chinook.Core
      • See details in the next step
    • Chinook.Data.EF
      • This is where the Repository Implementations and Unit of Work classes will live.
    • Chinook.Infrastructure
      • This is where the Service Implementations will live.
  3. Create the following three directories within the Chinook.Core Project:
    • Domain
      • This is where the Domain Model object will live.
    • Repository
      • This is where the Repository Contracts will live.
    • Services
      • This is where the Service Contracts will live
  4. Create the following directory within the Chinook.Infrastructure Project:
    • Services
At this point, the Chinook Solution should look similar to the following screenshot: solutionShot00

3) Generate an EF4 Data Model from an Existing Database

Right-click the Chinook.Data.EF Project and select ‘Add / New Item…’ efmWizard00 Next, select ADO.NET Entity Data Model from the Data Templates list, name it ‘Chinook,’ and click ‘Add’ efmWizard01 Next, select ‘Generate from database’ and click ‘Next’ efmWizard02 Now it’s time to point the EF Data Model to the Chinook database created in step ‘1) Create a Database.’  Go ahead and locate your database (or create a New Connection) and make sure that it is selected in the database drop-down-list.  Also, click the ‘Save entity connection settings in App.Config as:’ checkbox and leave the default Connection settings name.  Next click ‘Next.’ efmWizard03 Next, choose the database object that you want to model.  For this series, just choose the ‘Table’ objects by selecting the checkbox next to the ‘Tables’ node.  Click both of the checkbox options and the default Model Namespace and click ‘Finish.’ efmWizard04 The result is the EF data model that points to the 'Chinook’ database – Chinook.edmx efmWizard05 Save the file and build the Chinook Solution. A few more steps before we wrap Part 1 up…
  1. Add a reference to the ‘System.ComponentModel.DataAnnotations’ assembly to the Chinook.Core project.
  2. Add a reference to the Chinook.Core project to the other two projects: Chinook.Data.EF and Chinook.Infrastructure
  3. Make note of the namespaces of the following three directories within the Chinook.Core project – you will need these for Part 2 of the series
Directory Namespace
Domain Chinook.Core.Domain
Repository Chinook.Core.Repository
Services Chinook.Core.Services
In summary, we’ve created a new database, created a new Visual Studio application solution and project structure, and generated an Entity Framework data model from an existing database.

In the next post in this series, we’ll walk though the steps of creating Plain Old CLR Objects (POCOs) Repositories, Services, and a Unit of Work (UoW) using some T4 templates to generate all the aforementioned code.

Thanks for reading…

6 comments:

Akhil said...

Thanks a lot Ryan. This really helped me a lot. Great detailed approach for beginners.

Akhil Parasa said...

Could you Provide a basic sample implementation for WebForms? as IDependencyResolver seems to be an MVC 3 concept.

Thank You.

tdryan said...

Thanks for the comment Akhil. The concept of Dependency Injection is a bit convoluted in Web Forms as Web Forms Page and User Controls (via Page/UserControl classes) do not support constructor injection. You could potentially use property injection or just instantiate objects like you would normally do; however, this approach is not conducive to unit testing. The following contains a couple of snippets for DI registration in non-IDependencyResolover supported scenarios: Link. I hope this helps...

Akhil Parasa said...

Sure, it did. Thank You.

Also, i have a requirement where in the Object Context Provider Connection String needs to be based on User Login (using Forms Authentication, and membership). Is there a Thread Safe way (per HTTP Request) to Inject Dependency Dynamic Connection String From Session?

Thanks.

tdryan said...

I suppose your scenario is possible via structuremap's constructor (with parameters) injection; however, I don't recall ever injecting parameters (FWIW - that's a very odd requirement - per-user connection string). EF Object Context requires metadata (used for ORM mapping) in the connection string, making property injection a bit more challenging. I believe structuremap also supports parameterized strings, so you could have a connection string with {0} -based templates (containing the full connection string with {0} templates for the respective user name/id) and inject the user with string.Format. I recommend that you throw a question out on StackOverflow presenting your specific (or similar) scenario. I know that doesn't specifically answer your question, but hopefully that points you in the right direction. Good luck Akhil... -Dan

Akhil said...

Sorry to Bug You, but i have one more question on the Article (im an absolute beginner to EF4, SoC paradigm).

So, The EF4_T4 template Generates IServices in Core proj and The Infrastructure Project implements those. So, according to DDD, do i assume Infrastructure is my BLL, and implement a Constructor with Respective IRepositiory and initialize it as done in Web-> Models - > Albums -> AlbumGridViewModelBuilder.cs?

Essentially i need to provide Concrete implementation for Services in the Infrastructure Project and use them in my Web Pages?