At the end of the last post, I had a solution with multiple projects. One of the projects contained the POCO domain model and another project leveraged EF Code First to read/write the domain model to a dynamically created SQL Server database. The goal of this post is to use ASP.NET MVC Web API to surface database data to the client browser.
Most of my career I have spent on the server side of things moving data between layers. I have been part of teams where we created our own application infrastructure as well as a user of IdeaBlade’s DevForce, WCF RIA Services, CSLA, etc.
In the last year, I have had the pleasure of learning from Jon Sarker who is a senior software architect at ProModel. Jon has helped ProModel streamline moving data efficiently and quickly through the use of enterprise design patterns such as Repositories, Commanding, Factories (for repos and commands in particular), DTOs, Request/Response objects, etc. Once you understand and start using these data design patterns, everything seems so modular, clean and maintainable.
The focus in this blog post will be documenting the process of using Mr. Papa’s Code Camper code to do the following against the gamification service domain model:
1. Build Repositories
2. Build Unit of Work with Repository Factories
3. Web API Controllers
I recommend reading Patrik Lowendahl’s “The repository pattern explained and implemented” which contained the following definition for the Repository Pattern found here.
“Mediates between the domain and the data mapping layers using a collection-like interface for accessing domain objects.”
So far, LobGame.Data.Contracts is empty. Borrowing from John, I put the following IRepository interface in the “LobGame.Data.Contracts” project.
I must admit I hit a case of analysis paralysis here. Mr. Papa used Int as the data type for his unique identifier. My domain object classes used a mix of string and Guid as the unique identifiers therefore I needed the flexibility of the Object type.
I will be using Entity Framework to get/save data from the SQL Server database. The following is the concrete implementation of the IRepository using EF.
As long as I fetch data through the IRepository interface, no one needs to know under the hood I am using Entity Framework. I love how the EFRepository provides basic CRUD operation for free. This will allow me to get something up and running really fast and then override to optimize later as needed.
Notice the “GetAll” returns IQueryable<T>. From my previous experience with Repositories, I have debated the value of returning IQueryable<T> in our repositories. Just for food for thought, I share the following links for perhaps a future debate.
Build Unit of Work with Repository Factories
I do not have much experience with the Unit of Work pattern. Seeing it in action I see the value. Martin Fowler defines Unit of Work pattern as:
“Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems.”
In previous web services I built, it would be common to instantiate 1 to many repositories in a command or service constructor. With the UoW, I have easy access to all repositories. It allows one to derive a base class more easily and simply put the UoW in it.
Again. borrowing directly from Mr. Papa, I put the following interface for ILobGameUow in the “LobGame.Data.Contracts” project.
The interface is simple basically containing a repository for each class in the domain model.
The concrete implementation is found in the “LobGame.Data” project and is shown below.
The concrete implementation of the “Unit of Work”
1) Decouples the Repositories from the controllers
2) Decouples the DbContext and Entity Framework from the Web API controllers
This class implements the “Unit of Work” pattern in which the “UoW” serves as a facade for querying and saving to the database. Querying is delegated to “repositories”. Each repository serves as a container dedicated to a particular root entity type such as an Application. A repository typically exposes “Get” methods for querying and will offer add, update, and delete methods if those features are supported. The repositories rely on their parent UoW to provide the interface to the data layer which in this implementation is the EF DbContext.
There are 2 methods within the UoW that know how to return a repository based upon the domain model entity type. GetStandardRepo<T> will create the most basic repository based upon EfRepository. GetRepo<T> will find a specialized version you have created for a specific domain model entity. For brevity, I am not showing some Factory classes. Perhaps I will follow up in a later post. You can find them here.
At this point, I have not created any specialized repositories yet so notice the UoW is always calling GetStandardRepo<T>. I will create some specialized repositories in the next blog post. For now, repositories will only provide the ability to GetAll, GetById, Add, Delete and Update using the generic EFRepository implementation.
Web API Controllers
With the Repositories and UoW defined, getting a working version of a web API is pretty easy. I need an APIController for each domain model class. Each controller ideally should have access to the UoW therefore ApiControllerBase makes sense to be created.
If you compare this to the John Papa’s Code Camper application, you will notice its use of Inversion of Control to define the UoW. If requested, I will discuss IoC in a later blog post.
Next, I created my first APIController for my Application entity and derived it from ApiControllerBase. I right clicked on the “Controllers” folder and added the following:
I then modified the template ApplicationsController to be derived from ApiControllerBase. I added a constructor which constructed the repository factories and ultimately a LobGameUow.
As you can see above, just to see if things were working, I implemented the Get() method by simply calling into Uow.Applications.GetAll().
Oh yeah, I commented out creating the LobGameDbcontext in the Global.asax.cs from the previous post since LobGameDbcontext will be creating as part of the UoW contruction within the ApiControllerBase.
Before we run this, let recap the blog series so far:
1. In “Model” project, built the domain objects.
2. In “Data” project built the DbContext referencing the domain objects in the DbSets. EF Code First created and seeded the database.
3. In “Data.Contracts” project,
a. Added 2 interfaces IRepository and ILobGameUow.
b. Added “Helpers” folder for Repository Factory classes.
4. In “Data” project, created 2 concrete classes EFRepository and LobGameUow. LobGameUow simply contains repositories for each class in the domain model.
5. In “Web” project, created our first ApiController for Application.
If you run the project, you will get the home page provided by the Visual Studio MVC4 template as shown here.
I replaced the url with this http://localhost:58016/api/applications and voila, data is returned as seen below.
You can see data from the SQL Server database is being returned to the browser. Notice however that the format is XML whereas we would like it to be in JSON. To address this, John Papa added the following class to LobGame.Web project’s “App_Start” folder which removes the Xml formatters from the HttpConfiguration.
Now call this new class within Global.asax.cs.
Rerun and voila, JSON now.
Typing in “/api/applications/?id=a3963393-926a-464b-8525-1ef4ad8a2022” will fetch just a single application with that id.
The majority of the code I have discussed is “write once” plumbing such as IRepository, EFRepository, APIBaseController, RepositoryFactories, RepositoryProvider, etc. With the plumbing already written, one can easily surface data to a browser by simply creating:
1. Domain Model
This blog post gave a high level overview of some data design patterns such as Repositories and Unit of Work and ended with fetching data from the database for one of the classes in the domain model. In the next blog post, I will most discuss adding, deleting and updating data through the Web API for at least 2 of the domain model classes.
Possible Future Discussion Points
The following list of topics is things I skimmed over or ignored altogether. If you are interested in one of these let me know.
· Repository Factories deep dive
· ASP.NET MVC and Inversion of Control using Ninject
· Pros/Cons of returning IQueryable<> from Repositories
· Int versus Guid for unique identifier
· If I don’t get burned out, I think a good future task would be to swap out the client and server infrastructure with Breeze.js and DevForce.
· Microsoft Upshot