Tag Archives: MVP

Home Library

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

This year I have set a little project for myself. A bit of background first. Last year I released a project called WinformsMVP which is an MVP framework for the Winforms platform. The example code that I provided with the source was quite trivial. Previous to that, in my first year as a programmer, I created a Winforms application which assisted my study for the Winforms MCTS certification. I thought it would be nice to take that application and re-implement it using the WinformsMVP framework. I will also take the opportunity to use up-to-date tools like Entity Framework 6 (code first) and perhaps a few other little utilities which I have come across in my travels.

I have already made a start on the application which I am going to call Home Library. It is basically an application which individuals can use to track their lendings of books to others. I’ve lost many books over the years where they have not been returned and I did not track who I lent it to. This application helped me address that and it was fun to make.

The code for this project is available at this GitHub repository. I plan to tag the code at various milestones and the tag for the current state of the code is called DataAccessAndDomain_1. Mind you, that doesn’t mean I won’t go back and re-factor code. But I think tagging it at various milestones will be helpful as I make blog posts with regards to the project, as it progresses.

I don’t have much in the way of Business Analysis skills; and in any case, I am the client and subject-matter expert here. So I got to work and created the domain classes which I used to generate my database. The database schema looks like this (diagram generated using the Entity Framework Power Tools): Home Library Schema

To give you an idea of the domain classes, here are a couple which I have created:

public class Book
{
	public int Id { get; set; }
	public string Title { get; set; }
	public Edition Edition { get; set; }
	public Publisher Publisher { get; set; }
	public int PublisherId { get; set; }
	public BookType TypeOfBook { get; set; }

	public virtual ICollection<Person> Authors { get; set; }
	public virtual ICollection<Comment> Comments { get; set; }
	public virtual ICollection<BookCover> Covers { get; set; }
	public virtual ICollection<Lending> Lendings { get; set; }
}
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; }
}

Those classes are in a separate project called HomeLibrary.Model.
You can see in the book class I have created a couple of enums. As Entity Framework 6 supports enums, it made sense to use them for abstractions which represented a finite number of options. The BookType enum looks like this:

public enum BookType
{
	TextBook = 0,
	Novel = 1
};

For the classes which will do the actual querying, I created a separate project called HomeLibrary.Model.EF. The HomeLibraryContext (which inherits from DbContext) is as follows:

public class HomeLibraryContext : DbContext
{
    //  DbSets go here
    public DbSet<Book> Books { get; set; }
    public DbSet<BookCover> BookCovers { get; set; }
    public DbSet<Comment> Comments { get; set; }
    public DbSet<Lending> Lendings { get; set; }
    public DbSet<Person> People { get; set; }
    public DbSet<Publisher> Publishers { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        //  set up the Publisher's table
        modelBuilder.Entity<Publisher>().HasKey(p => p.Id);
        modelBuilder.Entity<Publisher>().Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        modelBuilder.Entity<Publisher>().Property(p => p.Name).IsRequired().IsVariableLength();
            
        //  set up the People table
        modelBuilder.Entity<Person>().HasKey(p => p.Id);
        modelBuilder.Entity<Person>().Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        modelBuilder.Entity<Person>().Property(p => p.Email).IsRequired().IsVariableLength();
        modelBuilder.Entity<Person>().Property(p => p.FirstName).IsRequired().IsVariableLength();
        modelBuilder.Entity<Person>().Property(p => p.LastName).IsRequired().IsVariableLength();
        modelBuilder.Entity<Person>().Property(p => p.Sobriquet).IsOptional().IsVariableLength();

        //  set up the Comment table
        modelBuilder.Entity<Comment>().HasKey(p => p.Id);
        modelBuilder.Entity<Comment>().Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        modelBuilder.Entity<Comment>().Property(c => c.CommentText).IsRequired().IsVariableLength();

        //  set up the Book table
        modelBuilder.Entity<Book>().HasKey(p => p.Id);
        modelBuilder.Entity<Book>().Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        modelBuilder.Entity<Book>().Property(c => c.Title).IsRequired().IsVariableLength();

        modelBuilder.Entity<BookCover>().HasKey(p => p.Id);
        modelBuilder.Entity<BookCover>().Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        modelBuilder.Entity<Lending>().HasKey(p => p.Id);
        modelBuilder.Entity<Lending>().Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);


        base.OnModelCreating(modelBuilder);
    }
}

You can see that I have opted for using the Fluent API for setting up the various tables rather than the Attribute-based API. Otherwise, it is a very straightforward context.

I faced an interesting scenario with seeding which I will leave for a separate blog post. The upshot of it was that I elected to do the database creation and seeding using the original EF Code First method of inheriting from a class which implements IDatabaseInitializer. As I wanted to drop and re-create the database each time I ran the application during development, I opted to inherit from DropCreateDatabaseAlways. The HomeLibraryInitializer looks like:

public class HomeLibraryInitializer : DropCreateDatabaseAlways<HomeLibraryContext>
{
    protected override void Seed(HomeLibraryContext context)
    {
        new List<Person> { new Person { FirstName = "Terry", LastName = "Halpin", Email = "hi", IsAuthor = false},
            new Person { FirstName = "Alan", LastName = "Turing", Email = "hi", IsAuthor = false }
            , }.ForEach(p => context.People.Add(p));

        context.SaveChanges();

        base.Seed(context);
    }
}

Stay tuned for future posts!

Twisting the Triad – MVC

I have spent a lot of time researching the difference between the MVC and MVP design patterns, as I could not really articulate those differences in a conversation, even though I have used them both in practice. When asking around, I found that a lot of other developers also did not actually know the difference either. So I was in good company.

When you go down this road, you encounter the phrase “Twisting the Triad”. The MVP pattern was arrived at by “Twisting the Triad” (among other things). But the many people who talk about twisting the triad never actually stop to explain what that means exactly. And when I started asking colleagues what is meant by that phrase, I was not surprised to find that no-one (not 1) person could explain what twisting the triad means. Rotating the nodes in the diagram is not quite good enough as an explanation because it has no context. And how far are they rotated? ** Blank looks all round **. Some guys thought it had something to do with the arrows in the diagram. Whilst the difference in the directed arrows between the MVC and MVP diagrams does encompass a huge part of the distinction between the 2 patterns, it does not, in any way, explain what “Twisting the Triad” means.

After much cogitation on the issue, I believed I worked it out one day during my morning shower. But I wanted back-up before I was sure. This theory gave me fresh keywords for Googling and I finally stumbled upon this post by a very well-respected guy in the ASP.NET MVC community. See the last paragraph under the heading The Difference?.

So, without further ado, let me explain what the phrase “Twisting the Triad” means, when used to explain how the MVC pattern evolved into the MVP patten. It is all about which node of the diagram is the first point of contact for the user gesture (or user request). Let me explain with an interactive diagram. The diagram below shows the MVC pattern with the nodes following this colour legend:

  • Red: Model
  • Green: View
  • Yellow: Controller

The arrow represents the user gesture. As you can see, with MVC, the first point of contact for the user gesture is the Controller, which then orchestrates how the application handles that user input.
Now, click the button with the text Twist the Triad!

User Gesture

When you twist the triad by clicking the button, the View now becomes the first point of contact for the user gesture, which is observed by the Presenter i.e. it raises events to the Presenter which then handles those events.

  • Red: Model
  • Green: View
  • Yellow: Presenter

So to recap, this post was about Twisting the Triad. I realise there are other differences between the two patterns. But I’m hoping this post clearly articulates the meaning of “Twisting the Triad”, which so many great developers cannot seem to explain.

ASP.NET Web Forms MVP

I like coding to patterns. And one pattern I really like is the Model View Presenter (MVP) pattern. Whilst the Patterns and Practices group’s implementation of this pattern (Web Client Software Factory) is good for big applications with a multitude of business modules, it is too heavy for smaller applications. This is where the ASP.NET Web Forms MVP project fills a niche nicely.

Put together by an Australian duo (Tatham Oddie and Damian Edwards), ASP.NET Web Forms MVP is a very nice implementation of the MVP pattern using the WebForms flavour of ASP.NET. With ASP.NET MVC all the rage these days, I like the fact that these guys went off and did their own thing, injecting new life into the WebForms universe. And they have incorporated messaging! Now that is really handy and feels like possible lessons learnt from some of the XAML technologies.

I have put together a really simple example to give you a taste. The charter I set for this example was to showcase the typical lifecycle of a request, starting at the View, going via the Presenter and hitting a data layer to retrieve some data from an XML file and display it in a grid (back on the View). There’s no paging or sorting on the Grid – unnecessary complexity for this style of example.

In the download code, you will find a solution with the following structure:

I have deliberately used the same prefix for the Logic and DataAccess projects (i.e. the name of the web project) as I have relied on convention for Presenter discovery.

Firstly, I need to create a model for my page:

public class DisplayAlbumsModel
{
	public List<Album> Albums { get; set; }
	public class Album
	{
		public string Id { get; set; }
		public string Artist { get; set; }
		public string Title { get; set; }
	}
}

This will provide the data context which I can hydrate in my Presenter and make available to my View.

Speaking of Views, I need an interface for the View:

public interface IDisplayAlbumsView : IView<DisplayAlbumsModel>
{
	event EventHandler RetrieveAlbums;
}

One event will do. This will be raised by the View to the Presenter, which will subscribe to it in its Load method. With composing components as the desired approach, we will now implement that View as a user control, over in the Webapp project. We will then chuck that user control on a very basic, bare-bones web page. The user control inherits from MvpUserControl<DisplayAlbumsModel>, strongly typed to my Model. It also implements IDisplayAlbumsView, raising the member event RetrieveAlbums in the Page_Load event handler:

public partial class DisplayAlbumsControl : MvpUserControl<DisplayAlbumsModel>, IDisplayAlbumsView
{
	protected void Page_Load(object sender, EventArgs e)
	{
		if (!IsPostBack)
		{
			RetrieveAlbums(this, EventArgs.Empty);
			this.AlbumsGridView.DataSource = Model.Albums;
			this.AlbumsGridView.DataBind();
		}
	}

	public event EventHandler RetrieveAlbums;

	protected void AlbumsGridViewRowcommand(object sender, GridViewCommandEventArgs e)
	{
		// do stuff here. E.g. redirect to a page with details about the selected album.
	}
}

Finally, over to the Presenter back in the Logic project, which inherits from the WebFormsMvp.Presenter class, strongly typed to our View:

public class DisplayAlbumsPresenter : Presenter<IDisplayAlbumsView>
{
	private readonly ChinookDbHelper dataAccessHelper;

	public DisplayAlbumsPresenter(IDisplayAlbumsView view) : base(view)
	{
		dataAccessHelper = new ChinookDbHelper();
		View.RetrieveAlbums += View_RetrieveAlbums;
	}

	void View_RetrieveAlbums(object sender, EventArgs e)
	{
		List<DisplayAlbumsModel.Album> albums = new List<DisplayAlbumsModel.Album>(); // a collection of Domain objects.
		var albumsData = dataAccessHelper.GetAlbums(); // get the tuples from the Data Layer

		//  Transform the raw data to a collection of Domain objects.
		foreach (var album in albumsData)
		{
			albums.Add(new DisplayAlbumsModel.Album {Artist = album.Item3, Id = album.Item1, Title = album.Item2});
		}

		View.Model.Albums = albums;
	}
}

The presenter discovery is done by convention. To demonstrate what the framework looks for, all I have to do is add a Typo to the Presenter’s namespace. The stack trace tells the whole story. First it looks for the PresenterBinding attribute (more on that later). After that, it searches for it in certain namespaces:

AttributeBasedPresenterDiscoveryStrategy:
– could not find a [PresenterBinding] attribute on view instance ASP.controls_displayalbumscontrol_ascx

ConventionBasedPresenterDiscoveryStrategy:
– could not find a presenter with type name WebFormsMvpSimplePage.DisplayAlbumsPresenter
– could not find a presenter with type name WebFormsMvpSimplePage.Logic.Presenters.DisplayAlbumsPresenter
– could not find a presenter with type name WebFormsMvpSimplePage.Presenters.DisplayAlbumsPresenter
– could not find a presenter with type name WebFormsMvpSimplePage.Logic.DisplayAlbumsPresenter
– could not find a presenter with type name WebFormsMvpSimplePage.DisplayAlbums
– could not find a presenter with type name WebFormsMvpSimplePage.Logic.Presenters.DisplayAlbums
– could not find a presenter with type name WebFormsMvpSimplePage.Presenters.DisplayAlbums
– could not find a presenter with type name WebFormsMvpSimplePage.Logic.DisplayAlbums

So we can see how managing naming convention can be used to wire up the components of the MVP pattern.

If you want to use the PresenterBinding attribute for Presenter discovery, that is easily implemented by decorating the usercontrol class as follows:

[PresenterBinding(typeof(DisplayAlbumsPresenter), 
ViewType = typeof(IView<DisplayAlbumsModel>), 
BindingMode = BindingMode.Default)]

The attribute is the WebFormsMvp.PresenterBindingAttribute which has 3 properties: BindingMode, PresenterType and ViewType. Further examination of that attribute is beyond the scope of this post.

I’d like to thank Oddie and Edwards for this cool and light framework. Perfect for the scenario where you don’t want the overhead of the Web Client Software Factory, but you want the trimmings, familiarity and RAD aspects of Web Forms, plus the testability that the MVP pattern provides.

Download Code