Tag Archives: Home Library

Querying in the Home Library

An index for these Home Library posts can be found here. The code in this post can be viewed in full at this tag of the repository.

In this post, I’m going to reference a fair bit of code to go through the approach I’ve taken to retrieving data in my application. With this application, I am employing something known as Command Query Separation. Note that I am not going crazy with this and having separate databases for queries and commands. There is only a single database. I’ve tagged the current state of the code and it can be viewed/downloaded from this tag reference on Github.

I have adopted an implementation of this by Steven Van Deursen which he writes about in this blog post. So you can reference that for more details, as I won’t be going into that level of granularity for my explanation. On to the code.

The use case that I created for myself was to retrieve a collection of Lendings, to be displayed in a grid. Being that a query is required, I created a Query object called GetLendingsPagedSortedQuery:

public class GetLendingsPagedSortedQuery : IQuery<IList<Lending>>
{
	public int PageNr { get; set; }
	public int PageSize { get; set; }
}

The interface which that implements is as follows:

public interface IQuery<out TResult>
{

}

You may find an empty interface a little underwhelming. However, it does have an important role to play and gives us plenty!

The query object itself is a little misleading in its nomenclature, as it is really just a carrier of meta-data for the query. You can include all sorts of properties which inform the kind of search that is required. But it doesn’t actually perform the querying of the database. That is done by the query handler (coming up). So what we have is a separation of data and behaviour (which seems to transgress the principles of object-oriented programming). But that separation is actually important, as the modern approaches for decoupling components and using dependency injection make working with complex objects more difficult. Separating out the data and behaviour gives us the flexibility we strive for in maintainable/scalable applications.

The handler for that query is contained in a class where I am storing all of the handlers (all of the handlers for Lendings anyway):

public class LendingsHandlers : 
	IQueryHandler<GetLendingsPagedSortedQuery, IList<Lending>>,
	IQueryHandler<GetLendingByPkQuery, Lending>
{
	private readonly IUnitOfWork _unitOfWork;
	private readonly IUniversalMapper _mapper;

	public LendingsHandlers(IUnitOfWork unitOfWork, IUniversalMapper mapper)
	{
		_unitOfWork = unitOfWork;
		_mapper = mapper;
	}

	public IList<Lending> Handle(GetLendingsPagedSortedQuery query)
	{
		 IList<Lending> lendings = new List<Lending>();

		 foreach (var lending in _unitOfWork.Lendings.Paginate(query.PageNr, query.PageSize, l => l.Id, l => true, l => l.Book.Authors, l => l.Borrower ))
		 {
			 var uiLending = new Lending();
			 lendings.Add(_mapper.Map(lending, uiLending));
		 }
		
		return lendings;
	}

	public Lending Handle(GetLendingByPkQuery queryObject)
	{
		var uiLending = new Lending();
		return _mapper.Map(_unitOfWork.Lendings.FindBy(l => l.Id == queryObject.Id).Single(), uiLending);
	}

	public void Dispose()
	{
		_unitOfWork.Dispose();
	}
}

All of the handlers implement the following interface:

public interface IQueryHandler<in TQuery, out TResult> : IDisposable 
	where TQuery : IQuery<TResult>
{
	TResult Handle(TQuery query);
}

Grouping them in the one class is not a problem as they all have different closed generic types. And it is just a design decision that I made. If you want, you can create a separate class for each handler. The UnitOfWork is responsible for data access operations and the mapper is just an abstraction of the Automapper mapper engine which maps my Domain objects to my Ui-flavoured Domain objects (refer to this post for elaboration, if required).

Now, we could just go right ahead and inject the relevant handler/s into our controllers. But Steven came up with a better way. He has implemented the Mediator design pattern and done it in a very clever way, as foreshadowed by my previous post which set the ground work for this aspect of this post.

Normally, when the Mediator pattern is implemented, the object which is the Mediator is a member of each of the Colleague objects. But with an innovative usage of the dynamic run-time, mixed in with some reflection and dependency injection, we can write a Mediator which does not need to be a member of its Colleagues. This reduces the infrastructure code we would need to write as the number of handlers grow. The Mediator which I am using in Home Library looks like this:

public sealed class QueryProcessor : IQueryProcessor
{
	private readonly IUnityContainer _container;

	public QueryProcessor(IUnityContainer container)
	{
		_container = container;
	}

	//[DebuggerStepThrough]
	public TResult Process<TResult>(IQuery<TResult> query)
	{
		var handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResult));

		dynamic handler = _container.Resolve(handlerType, "Queryor");

		return handler.Handle((dynamic)query);
	}
}

where the interface IQueryProcessor has just the one method:

public interface IQueryProcessor
{
    TResult Process<TResult>(IQuery<TResult> query);
}

I feel I can’t just leave you in the lurch and not explain how I configured the dependency injection for that, as it was a little challenging with Unity. In fact, I cheated and took the code from a StackOverflow question answered by Steven himself (which I converted to the expression-style of syntax, as I don’t like the SQL-style of syntax of LINQ):

/// <summary>
/// From http://stackoverflow.com/a/13859582/540156, as updated by me with expression-style syntax
/// </summary>
/// <param name="type"></param>
private void AutoRegisterType(Type type)
{
	const string Registration = "Registration";

	var handlerRegistrations = _serviceAssembly.GetExportedTypes()
		.Where(x => !x.IsAbstract)
		.Where(x => !x.ContainsGenericParameters)
		.SelectMany(x => x.GetInterfaces()
			.Where(i => i.IsGenericType)
			.Where(i => i.GetGenericTypeDefinition() == type)
			.Select(i => new { service = i, implementation = x })
			);

	foreach (var registration in handlerRegistrations)
	{
		_container.RegisterType(
			registration.service,
			registration.implementation,
			type.Name + Registration,
			new TransientLifetimeManager());
	}

	if (type == typeof(IQueryHandler<,>))
	{
		// Decorate each returned IQueryHandler<T> object with an
		// QueryHandlerValidatorDecorator<T>.
		_container.RegisterType(
			type,
			typeof(QueryHandlerValidatorDecorator<,>),
			"Queryor",
			new InjectionMember[] { new InjectionConstructor(new ResolvedParameter(type, type.Name + Registration)) }
			);
	}
	else if (type == typeof(ICommandHandler<>))
	{
            //... ommitted as not relevant here
	}
}

And I call that method with a simple invocation AutoRegisterType(typeof(IQueryHandler<,>)); in my DiContainerConfigurer class, which is one of the classes that runs on start-up to wire up all the dependency injection. You can see in lines 33 and 34 references to a decorator. That’s coming up next.

But before we get to that, I mentioned earlier the important role that the empty IQuery<out TResult> interface plays. Take a look at the following code in my presenter:

public class AddLendingsPresenter : Presenter<IAddLendingsView>, IDisposable
{
	private readonly ICommandProcessor _commandProcessor;
	private readonly IQueryProcessor _queryProcessor;

	public AddLendingsPresenter(IAddLendingsView view, ICommandProcessor commandProcessor, IQueryProcessor queryProcessor) : base(view)
	{
		_commandProcessor = commandProcessor;
		_queryProcessor = queryProcessor;
		View.ViewClosing += View_ViewClosing;
		View.CloseControl += ViewCloseControl;
		View.Load += View_Load;
		View.AddNewLending += View_AddNewLending;
	}

	void View_Load(object sender, System.EventArgs e)
	{
		var getPeopleSortedQuery = new GetPeopleSortedQuery {SortBy = "id"};
		var getBooksSorted = new GetBooksSorted {SortBy = "id"};

		IList<Book> books = _queryProcessor.Process(getBooksSorted)
		IList<Person> people = _queryProcessor.Process(getPeopleSortedQuery)
		
		var addLendingViewModel = new AddLendingViewModel
		{
			Books = new BindingList<Book>(books),
			People = new BindingList<Person>(people)
		};
	}
	// ...
}

If you look closely at lines 21 and 22 where the _queryProcessor (our mediator) is put into play, no casting is required. Compile-time support is provided by our query architecture, and that seemingly underwhelming IQuery<out TResult> interface gives us that strong typing.

The other really cool aspect of this architecture is the use of decorators to implement cost-cutting concerns. The next piece of code which I am going to set out shows how we can use the Decorator pattern to wrap a query handler with a class that performs validation before the handler is invoked. If you are unfamiliar with the Decorator pattern, one of its hallmarks is that the class which is decorating another class implements the same interface that the decorated class implements. Below, QueryHandlerValidatorDecorator also implements IQueryHandler<TQuery, TResult>. So, inside the Handle method of our decorator, we perform some validation of our query object (in this case, using the Validator in the System.ComponentModel.DataAnnotations namespace) and then call the Handle method of our query handler, or decorated object:

public class QueryHandlerValidatorDecorator <TQuery, TResult> : IQueryHandler<TQuery, TResult>
	where TQuery : IQuery<TResult>
{
	private readonly IQueryHandler<TQuery, TResult> _queryHandler;

	public QueryHandlerValidatorDecorator(IQueryHandler<TQuery, TResult> queryHandler)
	{
		_queryHandler = queryHandler;
	}

	public TResult Handle(TQuery query)
	{
		var validationContext = new ValidationContext(query);

		try
		{
			Validator.ValidateObject(query, validationContext, true);
			return _queryHandler.Handle(query);
		}
		catch (ValidationException validationException)
		{
			throw;
		}
		catch (Exception exception)
		{
			throw;
		}
	}

	public void Dispose()
	{
		_queryHandler.Dispose();
	}
}

For the purposes of this post, I’ve added a very basic annotation to the GetLendingsPagedSortedQuery class, and it is that which gets validated by our decorator:

public class GetLendingsPagedSortedQuery : IQuery<IList<Lending>>
{
	[Range(0, 100, ErrorMessage = "The Page Number cannot be less than 1.")]
	public int PageNr { get; set; }
	public int PageSize { get; set; }
}

If you want to see the validation fail, just go to the LendingsPresenter and change the PageNr of the GetLendingsPagedSortedQuery to -1.

Again, you can check out the code for the content referred to in this post by going to this tag of the code.

A Slice Through the Layers

An index of the HomeLibrary application posts can be found here.

As I mentioned in my last Home Library post, I was eager to do a slice through the layers to test out any possible flaws or problems in my general architecture so far. To facilitate this, I fired up Balsamiq and created a View of roughly how I want one of the screens to look. The screen which manages people:
People

Note that all I want to implement here is the grid, not the whole screen. Also, I probably don’t need to explain the low fidelity nature of Balsamiq, which ensures that we don’t get too weighed down by such things as colour-selection.

The main things I want to verify in this exercise is:

  • whether I have configured Automapper correctly;
  • that my dependency injection is in order; and
  • that the data is making it from the database to the View as expected.

I created a separate branch to do this exercise, and as always with GIT, it’s very easy to make that available – LayersSlice Branch

Firstly, I created a service which will feed data to a presenter:

public class HomeLibraryService : IHomeLibraryService, IDisposable
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IUniversalMapper _mapper;


        public HomeLibraryService(IUnitOfWork unitOfWork, IUniversalMapper mapper)
        {
            _unitOfWork = unitOfWork;
            _mapper = mapper;
        }

        public BindingList<UiModel.Models.Person> GetAllPeople()
        {
            var peopleRepository = _unitOfWork.People;
            PaginatedList<Person> peoplePaginated = null;

            peoplePaginated = peopleRepository.Paginate(0, 3);

            var uiList = new BindingList<UiModel.Models.Person>();

            _mapper.Map(peoplePaginated.AsQueryable(), uiList);

            return uiList;
        }

        public void Dispose()
        {
            //  This will be properly done in final code.
        }
    }

2 of the main things I want to verify can be ascertained right here. You can see that the parameters to the constructor are facilitating constructor injection by my dependency injection container. That is configured in my composition root, a.k.a. Program.cs:

    static class Program
    {
        private static IUnityContainer _container;

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Database.SetInitializer(new HomeLibraryInitializer());
            new HomeLibraryContext().Database.Initialize(true);

            var autoMapperBootstrapper = new MapperBootstrapper();
            autoMapperBootstrapper.Initialize();

            ConfigureIoc();

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new PersonView());
        }

        private static void ConfigureIoc()
        {
            _container = new UnityContainer();

            _container.RegisterInstance<IMappingEngine>(AutoMapper.Mapper.Engine)
                .RegisterType<IUniversalMapper, UniversalMapper>(new TransientLifetimeManager());

            _container.RegisterType<IRepositoryProvider, RepositoryProvider>(
                new TransientLifetimeManager(),
                new InjectionMember[] {new InjectionConstructor(new RepositoryFactories())}
                );

            _container.RegisterType<IUnitOfWork, UnitOfWork>(new TransientLifetimeManager());
            _container.RegisterType<IHomeLibraryService, HomeLibraryService>(new TransientLifetimeManager());

            PresenterBinder.Factory = new UnityPresenterFactory(_container);
        }
    }

The service also contains the code which I use to map a domain object to a Ui-model (objects which are more suited and shaped to the View for use in Viewmodels). With just two lines of code I’m able to map all of the properties from the domain’s PaginatedList to the Ui’s BindingList. Thank you Jimmy Bogard!

I’ve only created one View for this demonstration as I only needed to verify the slice through the layers. What you will see in the PersonView is that I have used the PresenterBinding attribute to bind the View to the PeoplePresenter:

[PresenterBinding(typeof(PeoplePresenter))]
public partial class PersonView : MvpForm, IPersonView
{
	public PersonView()
	{
		InitializeComponent();
	}

	private void PersonView_Load(object sender, EventArgs e)
	{
		dgvPersons.AllowUserToAddRows = false;



		dgvcDelete.Image = ImageResources.delete;
		dgvcEdit.Image = ImageResources.edit;

		dgvPersons.DataSource = ViewModel.People;
	}

	public event EventHandler ViewClosing;
	public event EventHandler EditPersonClicked;
	public PersonViewModel ViewModel { get; set; }

	private void dgvPersons_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
	{
		switch (dgvPersons.Columns[e.ColumnIndex].Name)
		{
			case "dgvcIsAuthor":
				bool isAuthor;

				if (bool.TryParse(dgvPersons.Rows[e.RowIndex].Cells["dgvcIsAuthor"].Value.ToString(),
					out isAuthor))
				{
					e.Value = isAuthor ? ImageResources.tick : ImageResources.cross;
				}
				break;
		}
	}
	
	public void ReleasePresenter(IPresenter presenter)
	{
		PresenterBinder.Factory.Release(presenter);
	}

	protected override void OnClosing(CancelEventArgs e)
	{
		ViewClosing(this, EventArgs.Empty);
		base.OnClosing(e);
	}
}

WinformsMVP has 2 mechanisms for binding, that attribute and binding by convention. The reason I can’t use convention in my project is because my presenters will be located in a separate project which does not conform to the convention used by WinformsMVP to search for presenters. And that’s okay. It was a design choice I made. But if people prefer to bind by convention and to organise their projects in such a way that it conforms to that convention, then that’s okay too.

When the app is fired up, the following window loads:
PersonView

It’s not much to look at now, but this is just “proof of concept” time. The data is there and all is well for the plumbing, from top to bottom in the stack.

Note that a lot of the code in this post (in the branch referred above) will not look the same as I progress the project further. I have already moved forward and started putting in place the bootstrapping code in earnest.

Look out for a post in the near future which will talk about the query handling aspects of my architecture by virtue of the Mediator Pattern. Got to keep those presenters clean!

A Branching Strategy Using Git

An index of the HomeLibrary application posts can be found here.

Up until now, I have been performing commits against the master branch (and pushing to origin/master). But I recently came across this branching guide which made a lot of sense to me. You can download a pdf of the diagram here. As I am simulating a proper development process with the HomeLibrary application, I thought I should probably use some sensible branching principles.

So, my first (and only) step at this point was to create a development branch called develop and to commit my development work against that. I’ve also tagged the commit where the code branched as v0.1.0.0.. Had I been following this guide from the start, that tag would be my very first commit. Anyhow, I’m on track now with a branch/release management strategy. If I was to carve a snapshot out of that diagram, what I have done so far would be:
NewBranch

My next post will be a slice through the layers to display some simple data on a form; kind of a litmus test for my architecture so far.

Bringing Those Domain Objects to the View

An index of the HomeLibrary application posts can be found here.

In this post, I’m going to talk about my plan for bringing the domain objects in the HomeLibrary application, which are populated from the database, to the View. As I am using Entity Framework 6 Code First, the code-first objects which I create will be domain objects. This eliminates the need of having to map objects from the data layer (data-centric objects which may contain dataAccess-related code) to the domain. Arguably, you can also use these domain objects in the View itself. But in this project, I have elected to use some Ui-centric objects which will be used in the View.

I am not an architect, but this is my attempt at depicting the architecture for my domain and ui objects in the application:
POCOs

The idea being, that the domain objects do not travel any further than the domain (when coming from the data-layer). And going back in the other direction, the ui objects will also not go any further than the domain (they will not ever make it to the Data layer).

Data to View

When building enterprise applications, the idea is that we:

  1. pull data out of a database;
  2. apply applicable business rules on that data; and
  3. display that data.

That’s a very brief summary, of course. So in my architecture, once all the business rules have been applied to the domain objects, they will be ready to be transformed into ui objects, which will be used in the View.

To elaborate, I have a project called KesselRun.HomeLibrary.Model which will hold all of my domain objects e.g. Book, Person, Lending. Then, my ui objects will be contained in a project called KesselRun.HomeLibrary.UiModel e.g. Book, Person, Lending. As you probably observed, those objects by their names are identical. And in a very simple application like this, the classes which constitute those objects will be pretty much identical (albeit in different namespaces). However, in complex enterprise applications there can be a benefit in keeping your application as loosely coupled as possible. By having a separate set of objects for my ui layer, it makes it easier to change the set of domain objects, if required. Those changes won’t flow through to be ui, which will remain unaffected.

Another reason is that it is possible that the objects in the domain may contain logic which is not present in the objects of the ui and vice versa.

There are tools available which make it very easy to translate domain objects into ui objects. The one which I will be using in this application is called Automapper. Whilst this is not tutorial on Automapper (there is no shortage of those around), I will show you some code I have used in a library called KesselRun.HomeLibrary.Mapper (and I have tagged the code at Github so you can download the snapshot immediately following my implementation of that library).
Let’s look at an example. I will use Automapper to map the domain Person class (by map, I mean convert a populated object of one type to another):

public class Person
{
	public int Id { get; set; }
	public string Email { get; set; }
	public bool IsAuthor { get; set; }
	public string FirstName { get; set; }
	public string LastName { get; set; }
	public string Sobriquet { get; set; }

	public virtual ICollection<Lending> Lendings { get; set; }
	public virtual ICollection<Book> Books { get; set; }
}

to the ui Person class:

public class Person
{
	public int Id { get; set; }
	public string Email { get; set; }
	public bool IsAuthor { get; set; }
	public string FirstName { get; set; }
	public string LastName { get; set; }
	public string Sobriquet { get; set; }

	public virtual BindingList<Lending> Lendings { get; set; }
	public virtual BindingList<Book> Books { get; set; }
}

About the only difference here is that the Lendings and Books properties are ICollections in the domain version and BindingLists in the ui version.
Automapper requires configuration before the actual mapping. We have to teach it how to map from 1 type to another.

Configuration

I will start out with the Initializer. To that end, I have created an interface called IMappingInitializer:

public interface IMappingInitializer
{
	void Initialize();
}

The PersonInitializer which implements that looks like the following:

public class PersonInitializer : MappingBase, IMappingInitializer
{
	public PersonInitializer(Profile profile) : base(profile)
	{
	}

	public void Initialize()
	{
		Profile.CreateMap<Model.Person, UiModel.Models.Person>();
	}
}

It takes a Profile object as a parameter and it is that Profile object (from the AutoMapper library) which configures the relationship between the domain model and the ui model. One of the great things about AutoMapper is that if you have the exact same properties in both the mapping target and the mapping source, then you don’t need to do anything further in configuring that mapping relationship. However, if you needed to map a property in the source to a property in the target which has a different name, or if you didn’t want a particular property copied at all, then you would configure that here with that CreateMap method and your Initialize method might look something like:

public void Initialize()
{	
	Profile.CreateMap<Model.Person, UiModel.Models.Person>().ForMember(uiModel => uiModel.Email, domainModel => domainModel.MapFrom(a => a.EmailAddress));
	Profile.CreateMap<Model.Person, UiModel.Models.Person>().ForMember(uiModel => uiModel.Sobriquet, domainModel => domainModel.Ignore());
        ...
}

I have actually used the design pattern known as the Composition Pattern with regards to the initialization. A class called ViewModelMappings contains all of the individual initializers. And that class itself, also implements the IMappingInitializer interface.

public class ViewModelMappings : MappingBase, IMappingInitializer
{
	public ViewModelMappings(Profile profile)
		: base(profile)
	{
			
	}

	public void Initialize()
	{
		//  Initialize all individual mappings here
		new BookCoverInitializer(Profile).Initialize();
		new CommentInitializer(Profile).Initialize();
		new PublisherInitializer(Profile).Initialize();
		new BookInitializer(Profile).Initialize();
		new LendingInitializer(Profile).Initialize();
		new PersonInitializer(Profile).Initialize();
	}
}

The next thing we need to create is a custom profile which inherits from the Profile class from the Automapper library. It has a Configure method which we override and which calls the Initialize method of our ViewModelMappings object.

public class HomeLibraryProfile : Profile
{
	public const string ViewModel = "HomeLibraryProfile";

	public override string ProfileName
	{
		get { return ViewModel; }
	}

	protected override void Configure()
	{
		// initialize mappings here
		new ViewModelMappings(this).Initialize();
	}
}

We could have put each individual initialiser in this method. However, the use of the Composition Pattern enables us to arrange our code neatly. And if we decided we needed a suite of initialisers which were logically different from the ones inside the ViewModelMappings class, then we can implement that using the same design pattern. An example of that might be an object which handles the initialization of mappers going from the View back to the Domain (see below for discussion of that point).

In the final piece in the configuration jigsaw is the MapperBootstrapper class. The Initialize method of that class calls the static Initialize method of the Automapper.Mapper class. As you can see, we are adding our custom profile in the lambda expression and as a result of that, the Configure method in our custom profile object is called, therein initializing all of the initialization objects:

public class MapperBootstrapper
{
	public void Initialize()
	{
		var profile = new HomeLibraryProfile();
		AutoMapper.Mapper.Initialize(p => p.AddProfile(profile));
	}
}
Mapping

With the configuration done, I have created the following class which will do the lion’s share of the mapping:

public class UniversalMapper : IUniversalMapper
{
	private readonly IMappingEngine _mappingEngine;

	public UniversalMapper(IMappingEngine mappingEngine)
	{
		_mappingEngine = mappingEngine;
	}

	public virtual TDestination Map<TSource, TDestination>(TSource source, TDestination destination)
	{
		return _mappingEngine.Map(source, destination);
	}
}

It may come to pass that I have to create some custom mappers which are more specialized than that. Come what may.

As I mentioned earlier, the tag for the code for this stage of development is here. You’ll find everything I discussed in this post and more in that snapshot of the code.

Reverse Mapping with Automapper

When first using Automapper, the temptation to map from the View to the Domain is tantalising. The creator of Automapper cautions against this. Well, what he actually says is that it is fine to do it when your Domain is simple enough that you can get away with it. However, often in enterprise development the Domains can be complex such that a lot of friction is experienced in that reverse mapping process.

I’m sure my Domain will be very simple here. However, I am still not sure how I am going to approach writes and updates. I may implement some kind of command-processing infrastructure (which is crazy overkill for this little app), or I may just go the direct route through the layers. Until I have decided that, I am not sure whether reverse mapping will be on the cards. We’ll see.

A Unit of Work with Repositories Underpinned by DbContext – The DAL

An index of the HomeLibrary application posts can be found here.

I want to have a quick discussion about data access, as I have already re-factored this code in the HomeLibrary application. Originally, I just put in place a couple of simple repositories which looked like this:
Generalised Base Class

public abstract class RepositoryBase<T, TCxt> : IDisposable
	where T : class
	where TCxt : DbContext, new()
{
	public DbContext Context;
	public DbSet<T> Items;

	protected RepositoryBase()
		: this(new TCxt())
	{
		
	}

	protected RepositoryBase(TCxt context)
	{
		Context = context;
		Items = Context.Set<T>();
	}

	public T Create()
	{
		CheckDisposed();
		return Items.Create();
	}

	public void Add(T item)
	{
		CheckDisposed();
		Items.Add(item);
		Context.SaveChanges();
	}

	public T GetById(int id)
	{
		CheckDisposed();
		var set = Items.Find(id);
		return set;
	}

	public void Remove(T item)
	{
		CheckDisposed();
		Items.Remove(item);
		Context.SaveChanges();            
	}

	public void Update(T item)
	{
		CheckDisposed();

		var entry = Context.Entry(item);
		if (entry.State == EntityState.Detached)
		{
			Items.Attach(item);
			entry.State = EntityState.Modified;
		}
		Context.SaveChanges();            
	}
	
	public IList<T> GetAll()
	{
		CheckDisposed();
		return Items.ToList();
	}

	public abstract void CheckDisposed();

	public void Dispose()
	{
		if (!Context.TryDispose()) return;
		Context = null;
		Items = null;
	}
}

Domain-centric Repositories would Inherit from the Base Class

public class BookRepository : RepositoryBase<Book, HomeLibraryContext>, IBookRepository 
{
	public BookRepository()	{ }

	public BookRepository(HomeLibraryContext ctx) 
		: base(ctx)
	{ }

	public override void CheckDisposed()
	{
		if (Context == null)
		{
			throw new ObjectDisposedException("BookRepository");
		}
	}
}

I had a feeling there would be some better stuff out there which facilitated the repository-style access to the data via the DbContext. After a bit of searching, I stumbled upon this answer at stackoverflow. You can go there to read the code if you like (or here for my version), as it is quite large and not practical for me to repeat here.

It uses a unit of work to centralise access through a number of repositories. I liked the idea of this and when I went through the code, I recognised that it was quite sophisticated and written by someone who had really thought it through (and probably incorporated some hard learnt lessons). I made a couple of changes which I preferred, as I don’t just accept someone else’s code without scrutiny. I tagged that revision of the source DataAccessAndDomain_1.1, so it is available to download or read online.

This is definitely overkill for a simple book-lending application. However, I want to endeavour to use enterprise best practices for this sample application.