Monthly Archives: February 2014 - Page 2

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.

LocalDb – Where the Dbs Live and Some Simple Facts

I always forget where to find the mdf files which are created by localdb (hence this post).
If we take a look at the connection string, it’s not too instructional as to the location:

connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=ContosoUniversity2;Integrated Security=SSPI;"

In this post, I’ll identify the locations where you are likely to find that elusive localdb database.

Local AppData
Where you haven’t created the database yourself (perhaps you downloaded a project which creates and seeds the database via EF Code First), it can usually be found in this directory:
%AppData%\..\Local\Microsoft\Microsoft SQL Server Local DB\Instances\v11.0. Note the two dots before the string, Local, in that path. Without that, you’ll be dumped into the Roaming directory, which is not the right place.

User Profile
If you don’t find it there, another place it is often found is in the User Profile – %USERPROFILE%. When you create a new database in Sql Server, either through the GUI or by running the following Sql, the default path is in the %USERPROFILE% location:

create database SpiderMonkey

SQL Server Management Studio
Ultimately, you can dictate where the localdb mdf/ldf files for a database are created. Either through the GUI in SQL Server Management Studio, or by running the following into SQL Server Management Studio’s query window:

create database SpiderMonkey on (name='SpiderMonkey', filename='c:\DBs\SpiderMonkey.mdf')

Visual Studio
If you create a localdb database using Visual Studio, the default location is: %USERPROFILE%\AppData\Local\Microsoft\VisualStudio\SSDT
The following 2 pictures outline the workflow of using Visual Studio to create a localdb database. As you can see from the 2nd picture, you can choose where the mdf files are created:
CreateLocalDb4

CreateLocalDb3

As a final comment, the whole idea of localdb is that we developers should not need to be concerning ourselves with issues about the database. The team who created localdb did so with the intention of abstracting away the database so that we could focus on development. But it is still nice to know where to find these things, even if just to clean up your hard drive!

Fiddler’s Composer tab

As I have mentioned on previous occasions, Fiddler is a truly magnificent tool. I am always learning new ways to leverage its power and I’ve made a short screencast to highlight some of the stuff you can do with its Composer tab:

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.