- Base classes for an entity model
- A repository model for accessing entities
- Custom container installers for easily setting up our windsor container (or whatever container you want)
- Our own preset conventions for Fluent NHibernate
public T Get(object id) public void Save(T entity) public void Delete(T entity) public void DeleteAll() public IQueryable<T>AllThe repository pattern is very useful. It abstracts how we store and retrieve entities. This allows us to store them in a database when in production or in-memory with test data when writing tests. Once we have our repository all set up, we can look up a record by simply querying our repository for an instance of the entity we are looking for. This is achieved by:
Repository<Person>.Get(1);
Easy! that’s a really short line of code! Now, that’s if we know the ID of the object we’re looking for. What if we only know some of the properties of the thing or things we’re looking for? Well, you can query the repository using Linq like this:
Repository<Person>.All.Where(p => p.FirstName == "Al".SingleOrDefault());
Since All is an IQueryable, you can use Linq on it to your heart’s content. That’s really handy, but instead of reading from the database, what if we want to save something? All that is necessary is to create a new instance of one of our entities and send it back to the database like this:
using (var work = UnitOfWork.Begin()) { var person = new Person() { FirstName = "Your", LastName = “Name" }; Repository<Person>.Save(person); work.Commit(); }Entities are set up just like any old object. You can add whatever properties you like to them, but they inherit from a number of interfaces that help the entity map up to the database. We can combine the two examples above and read an entity from the database, modify its properties, and write it back.
using (var work = UnitOfWork.Begin()) { person = Repository<Person>.All.Where(p => p.FirstName == "Al").SingleOrDefault(); person.FirstName = "Alex"; Repository<Person>.Save(person); work.Commit(); }…and now Al’s name is “Alex” in our database. In the above code, you will notice a reference to a “unit of work.” What is that? It is a way of ensuring that all the commands contained inside our unit of work are committed on a single transaction. This is helpful if more than one person is accessing the database at the same time as us. It is worth noting that our current Caramel system implements the repository pattern using only NHibernate. We may implement other implementations, and you can always write your own that adheres to the IRepository interface, but out of the box you get NHibernate. Now I know what you’re thinking: “Al! This is really cool! How do I get started using this myself?” Well I have good news! To get a version of this running on your own machine quickly, you can pull our demo solution from: https://github.com/azolynsky/CaramelDemo All you have to do is run the included DBSetup.sql script inside of your SQL 2008 server (or other SQL server. Just make sure you modify the FluentConfigurationExtensions.cs and EntitiesInstaller.cs to use your version), and open the solution in Visual Studio. Once opened, you will see lots of comments and the same kind of code that I outlined here. You should be set up to access the database right out of the box after you run the DBSetup script. Check out how we connect to it in the solution, and try interacting with it in CaramelDemo/Program.cs.