Repository pattern and filters

Published 10/21/2009 by Henry in C# | LINQ | Patterns
Tags: , ,

In my previous post Multiple search criteria searching using Linq to SQL I talked about a way to implement multiple search criteria queries using LINQ to SQL.
Because I am doing some work using the ASP.NET MVC Framework, I looked into patterns to make a loosely coupled data layer. Ofcourse I checked out Rob Connery’s blog, he created the MVC Storefront (now Kona) the code can be found on MVC Sample Apps on Codeplex. Rob is leveraging the Repository pattern, this pattern provides dependency-free access to data of any type. I saw the screen cast where Ayende Rahien talks about ‘Filters and Pipes’.
Rob implements the filters in the MVC Storefront, I really like this approach, better than the approach in my previous post Multiple search criteria searching using Linq to SQL because it’s much cleaner, it is possible to ‘chain’ multiple criteria, but every criteria has it’s own extension method, thus following the single responsibility principle.
In my previous post in some cases I did too much in one method, I build up an IQueryable<post> for four search criteria, which breaks the Single Responsibility principle for one.

Using filters, which are extension methods that specify a filter on an IQueryable of something, makes it possible to let the calling party build up whatever they need. I know this can sound confusing, but I feel the following code example explains much better.

In my previous post, I called a few methods, and build up a IQueryable that way to satisfy every search criteria in the query.

   1:  [TestMethod]
   2:  public void Search_For_mvc_in_Title_And_Use_Paging_Test()
   3:  {
   4:   
   5:      MvcBlogDataContext repository = new MvcBlogDataContext("Data Source=.;Initial Catalog=MvcBlog;Persist Security Info=True;");
   6:   
   7:      var postsQuery = from p in repository.Posts
   8:                      select p;
   9:   
  10:      postsQuery = GetPostsQuery(postsQuery, "mvc", "", "", null);
  11:      postsQuery = GetPostsPagingQuery(postsQuery, 0, 5);
  12:   
  13:      List<Post> posts = postsQuery.ToList();
  14:   
  15:      Assert.IsNotNull(posts, "DataContext did not return posts when searching for 'mvc' in title");
  16:      Assert.AreEqual(posts.Count, 2, "DataContext did not return 2 posts when searching for 'mvc' in title");
  17:  }

Listing 1

Consuming filters
Would not it be cool if we could use a fluent interface-like way to query the data, so it will be obvious to what we want to query?
Something like the code (also in a Unit test manner like the previous post) in listing 2:

   1:  [TestMethod]
   2:  public void Search_For_mvc_in_Title_With_Paging_Test()
   3:  {
   4:      List<Post> posts = GetPosts().WithTitleLike("mvc")
   5:                                   .WhereTagsContain("")
   6:                                   .WhereBodyContains("")
   7:                                   .WithPaging(0, 5)
   8:                                   .ToList();
   9:   
  10:      Assert.IsNotNull(posts, "DataContext did not return posts when searching for 'mvc' in title");
  11:      Assert.AreEqual(posts.Count, 2, "DataContext did not return 2 posts when searching for 'mvc' in title");
  12:  }

Listing: 2

 

I think it is clear that the code in listing 2 is far more readable, than the code in listing 1. Another advantage is that it is easy to reuse every part of the query whenever it is needed.

Get all()
First I create a method that returns all Posts present in the database as an IQueryable<Post>. By the way, I am not using Dependency Injection, or Inversion of Control in this example, because it does not help in explaining the filters concept. BUT I think that when using this technique in a real world application, it is  a good thing to use IoC (StructureMap, Windsor, Ninject, Unity, whatever…).

   1:  public IQueryable<Post> GetPosts()
   2:  {
   3:      var postsQuery = from p in repository.Posts
   4:      select p;
   5:      return postsQuery;
   6:  }

Listing: 3

Extension methods
Leveraging extension methods, a .NET Framework 3.0 feature in combination with the IQueryable<T> interface, it is possible to create the filters. The class needs to be static and public, the extension methods also need to be static and public.
The first parameter specifies which type the method operates on and needs to be preceded by the ‘this’ modifier.

   1:  public static class PostFilters
   2:  {
   3:      public static IQueryable<Post> WithTitleLike(this IQueryable<Post> postsQuery,
   4:                                             string title)
   5:      {
   6:          if (!string.IsNullOrEmpty(title))
   7:              postsQuery = postsQuery.Where(p => p.Title.Contains(title));
   8:   
   9:          return postsQuery;
  10:      }
  11:   
  12:      public static IQueryable<Post> WhereTagsContain(this IQueryable<Post> postsQuery,
  13:                                                string tags)
  14:      {
  15:          if (string.IsNullOrEmpty(tags))
  16:              return postsQuery;
  17:   
  18:          return postsQuery.Where(p => p.Tags.Contains(tags));
  19:      }
  20:   
  21:      public static IQueryable<Post> WhereBodyContains(this IQueryable<Post> postsQuery,
  22:                                                 string bodyText)
  23:      {
  24:          if (!string.IsNullOrEmpty(bodyText))
  25:              return postsQuery;
  26:   
  27:          return postsQuery.Where(p => p.Body.Contains(bodyText));
  28:      }
  29:   
  30:      public static IQueryable<Post> IsCreatedOn(this IQueryable<Post> postsQuery,
  31:                                           DateTime? createdOn)
  32:      {
  33:          if (!createdOn.HasValue && createdOn.Value == DateTime.MinValue)
  34:              return postsQuery;
  35:   
  36:          return postsQuery.Where(p => p.CreatedOn.Value.Date == createdOn.Value.Date);
  37:      }
  38:   
  39:      public static IQueryable<Post> WithPaging(this IQueryable<Post> postsQuery,
  40:                                          int? startRow,
  41:                                          int? rowCount)
  42:      {
  43:          if ((!startRow.HasValue) && (!rowCount.HasValue || rowCount.Value == 0))
  44:             return  postsQuery;
  45:   
  46:          return postsQuery.Skip((int)startRow).Take((int)rowCount);
  47:      }
  48:  }

Listing: 3

In listing 3 it is obvious that every method has its own responsibility, it is easily maintainable and very readable. I think this is an elegant solution for the problem I tried to solve in my previous post, I found this better technique and want to share.

Henry Cordes
My thoughts exactly…


 Also take a look at: >> Part 2

Multiple search-criteria searching is a often encountered requirement that is not always straight forward to implement. These days we have NHibernate, Entity Framework, LBLGen, LINQ to SQL and many more.
I find that the choice for an ORM is hard, simply because there is so much to choose from.
I will not go in the choice for one or the other, but will use LINQ to SQL in this example, in my opinion if you only need a one to one mapping of your database tables to domain objects and your database does not contain a lot of tables LINQ to SQL is the way to go. LINQ to SQL is intuitive, the querying of the DataContext works as you would expect it to work and the performance is better than a lot of stored procs and T-SQL I have seen running in production at some of my clients :-).
So in this post I am going to show how to implement a search using multiple search criteria with LINQ to SQL.

The table I use in my example is a simple table called Post, it only has a few fields (see picture 1).

Pic 1: The SQL Server design of the Post table
Pic 1: SQL server design of Table ‘Post’

T-SQL
So how do we search
with T-SQL, if we want the query to return all records of the ‘Post’ table where the Title field contains the text “mvc”.
So in T-SQL, that would be:

   1:  SELECT PostId, Title, … FROM Post WHERE Title LIKE ‘%mvc%’

Listing 1: T-SQL example LIKE query

Right? In T-SQL we have to place wildcards (the ‘%’) around the search criterion we use with the LIKE operator to get the behavior that records where the Title field is “asp.net mvc framework” will be returned also, not only the records where the title field has the exact value: “mvc”.

When we execute the sql directly in the SQL Server Manager the result shows 2 rows (see picture 2).

Pic 2: Execute T-SQL in SQL Server directly
Pic 2: Execute T-SQL in SQL Server directly

LINQ to SQL model
I use LINQ to SQL to create a model (or a DataContext). The model shows the ‘entity’ you see in picture 3. As I mentioned earlier it is a one to one mapping with the SQL table from picture 1.

Pic 3: The LINQ to SQL designer shows the Post entity
Pic 3: Post entity in LINQ to SQL model

Unittest
To easily proof how many rows will be returned
I create a unittest, that instanciates the MvcBlogDataContext and does a search in the Post table. The LINQ query also looks if the Title field of the Post table contains the text “mvc”. In the test the ‘Contains’ operator is used. ‘Contains’ in LINQ to SQL works exactly the same as the LIKE with the ‘%’ wildcards in listing 1. 

   1:  [TestMethod]
   2:  public void Search_For_mvc_in_Title_Test()
   3:  {
   4:    MvcBlogDataContext repository = new MvcBlogDataContext("Data Source=.;Initial Catalog=MvcBlog;Persist Security Info=True;");
   5:    List<Post> posts = repository.Posts.Where(p => p.Title.Contains("mvc")).ToList();
   6:   
   7:    Assert.IsNotNull(posts, "DataContext did not return posts when searching for 'mvc' in title");
   8:    Assert.AreEqual(posts.Count, 2, "DataContext did not return 2 posts when searching for 'mvc' in title");
   9:  }

Listing 2: Unittest that proofs 2 records are in database

The test does an Assert on the posts object not being Null and on the number of posts in the posts object (List<Post>) being two. When we execute the test, will the test pass, or fail?

Pic 4: The unittest to proof we have 2 rows containing 'mvc' in the Title field of the Post table passed succesfully
Pic 4: Unittest to proof we have 2 rows containing 'mvc' in the Title field has passed

The test passed, the result returns two rows, so we now know two rows in the Post table contain a Title field that contains "mvc".

Make a search with multiple search criteria
Now when we have one search criterion, the LINQ to SQL query is straight forward. But in real life the requirements are in a lot of cases that you have a lot of search criteria, which can be used alone, or in combinations. So how do we go about in making a search with multiple search criteria?

   1:  [TestMethod]
   2:  public void Search_For_mvc_in_Title_And_Use_Paging_Test()
   3:  {
   4:    MvcBlogDataContext repository = new MvcBlogDataContext("Data Source=.;Initial Catalog=MvcBlog;Persist Security Info=True;");
   5:   
   6:    var postsQuery = from p in repository.Posts
   7:                     select p;
   8:   
   9:    postsQuery = GetPostsQuery(postsQuery, "mvc", "", "", null);
  10:    postsQuery = GetPostsPagingQuery(postsQuery, 0, 5);
  11:   
  12:    List<Post> posts = postsQuery.ToList();
  13:   
  14:    Assert.IsNotNull(posts, "DataContext did not return posts when searching for 'mvc' in title");
  15:    Assert.AreEqual(posts.Count, 2, "DataContext did not return 2 posts when searching for 'mvc' in title");
  16:  }

Listing 3: Unittest search with multiple search criteria and paging

Listing 3 shows a unittest that uses the MvcBlogDataContext, the by LINQ to SQL generated datacontext. Om line 6 the postsQuery object inferes it’s type (IQueryable<Post>) from the LINQ Query that selects all posts in the datacontext.
Line 9 in listing 3 calls a method GetPostsQuery that expects an IQueryable<Post> object and some other parameters (our search criteria). We pass the postQuery that selects all posts from the datacontext.

Line 10 in listing 3 does almost the same trick, but than with other parameters, the GetPostsPagingQuery extends the query with Paging criteria and returns the extended query again as an IQueryable<Post> object.

Line 12 in listing 3 executes the query by calling ToList().

Line 14 in listing 3 does an Assert on the posts object not being Null and the next line asserts the number of posts in the posts object (List<Post>) being two.

Multi search criteria LINQ to SQL query
The following listing (4) shows the method GetPostsQuery, the method that does the actual work of building the LINQ Query according the values of the search criteria. The method’s first parameter is of type IQueryable<Post>, it returns an IQueryable<Post> also. When we use IQueryable<T> it is possible to pass LINQ queries around and extend it. 
The method in listing 4 does check for every criteria (parameter) if it has a valid value. If it doesn’t, nothing happens and we move on. If a parameter (search criterion) does contain a valid value the method will extend the query by adding the criterion to the query. For nvarchar fields the Contains operator is used. Again ‘'Contains’ works exactly the same as the LIKE with the ‘%’ wildcards from listing 1.

   1:  /// <summary>
   2:  /// Gets a LINQ to SQL Query according the provided parameters
   3:  /// </summary>
   4:  /// <param name="postsQuery"></param>
   5:  /// <param name="title"></param>
   6:  /// <param name="tags"></param>
   7:  /// <param name="createdOn"></param>
   8:  /// <param name="bodyText"></param>
   9:  /// <returns></returns>
  10:  private IQueryable<Post> GetPostsQuery(IQueryable<Post> postsQuery, 
  11:                                         string title, 
  12:                                         string tags, 
  13:                                         string bodyText,
  14:                                         DateTime? createdOn)
  15:  {
  16:      if (!string.IsNullOrEmpty(title))
  17:          postsQuery = postsQuery.Where(p => p.Title.Contains(title));
  18:   
  19:      if (!string.IsNullOrEmpty(tags))
  20:          postsQuery = postsQuery.Where(p => p.Tags.Contains(tags));
  21:   
  22:      if (!string.IsNullOrEmpty(bodyText))
  23:          postsQuery = postsQuery.Where(p => p.Body.Contains(bodyText));
  24:   
  25:      if (createdOn.HasValue && createdOn.Value > DateTime.MinValue)
  26:          postsQuery = postsQuery.Where(p => p.CreatedOn.Value.Date == createdOn.Value.Date);
  27:   
  28:      return postsQuery;
  29:  }

Listing 4: IQueryable<Post> GetPostsQuery, extends and returns the IQueryable<Post> query

Listing 5 contains the method GetpostsPagingQuery. This method also extends and returns the query. LINQ to SQL provides paging with the Skip (skip all rows untill) and Take (take n number of rows) methods. And this method uses these methods to extends the query with paging capabilities.

   1:  private IQueryable<Post> GetPostsPagingQuery(IQueryable<Post> postsQuery,
   2:                                         int? startRow,
   3:                                         int? rowCount)
   4:  {
   5:      if ((startRow.HasValue) && (rowCount.HasValue && rowCount.Value > 0))
   6:          postsQuery = postsQuery.Skip((int)startRow).Take((int)rowCount);
   7:   
   8:      return postsQuery;
   9:  }

Listing 5: Adds paging to query, using Skip and Take methods

We have everything wired up, all we have to do is execute the TestMethod in listing 3. In this test we only check for the title field to contain the text “mvc”. I think the idea is quite obvious, but in this post i do not really test it. So when I run the test, it passes, the test returned the same two rows like before:

 
Pic 5: The unittest that executed the programatically created LINQ Query according the search criteria passed succesfull

With LINQ to SQL it is possible to code queries that have to search using one or more search criteria in a structured and type safe way. It is not necessary to use string concatenation using wildcards. With LINQ to SQL we can solve this problem in a more elegant way. The fact that the SQL generated by LINQ to SQL performs really well is the icing on the cake. Or are you the type of developer that likes to write stored procs that 90 % of the time are the same but only the field and tablenames vary…

Henry Cordes
My thoughts exactly…


In a recent post, I talked about a project where the requirement is to create modules that can be used in an ASP.NET webapplication and in Sharepoint 2007, where I wanted to have separations of concerns. The way I solved this is: creating ASP.NET UserControl libraries (inside their own ASP.NET Webapplication project) that we package inside Sharepoint webparts. During development we test and debug the modules in a separate ASP.NET webapplication. We use pre-build events to copy the ascx files from the UserControl libraries to this webapplication and because we set a reference to the  webapplications, the dll’s are available already. Scott Guthrie has a tutorial on his website that explains how we do this. 

In the post I said I wanted to leverage Unity as our Inversion of Control Container and I was thinking about using the WCSF, because I wanted to use the MVP design pattern.
After some prototyping, I came to the conclusion using WCSF was not practical for our purpose.  Still I wanted to use the MVP pattern, because of unit-testing and loose coupling needs. I could not use MVC, because of the Sharepoint requirements.

The Model-View-Presenter pattern is different from MVC or Model-View-Controller in the sense that with MVC the Controller is where the request comes in and the Controller is where you control (what’s in a name…) your View and what you get from the Model.
With MVP the request comes in at the View, the View than delegates it to the Presenter that will get data from the Model and returns it back to the View.

Model View Presenter pattern Pic 1.: Model View Presenter pattern

The solution I finally found to be working really good is using the MVP design pattern and Unity in the following manner.

Model View Presenter UserControl diagramPic 2.:Model View Presenter Class Diagram 

As you can see in picture 2 the Model, View and Presenter all are implementing an interface. Practicing Interface based programming sets the door wide open for leveraging an Inversion of Control container, or IoC container. In my case I am using Unity, because I am doing this project for a client who is heavily into using Microsoft tools. All Presenters are derived from the abstract class Presenter<TView>.


Pic 3.: Interfaces used in MVP diagram

Why the interfaces?
Using Interfaces for all these parts of our component makes it easy to use an IoC container. Our objects are loosely coupled and we can switch out the concrete implementations easily, because we program against the interfaces. Say we want to test the Presenter and to avoid having a dependency on a data store or some service we want to switch the Model out for an implementation that returns the same hard coded objects each time. all we have to do is create this ‘mock’ Model that implements the IZaakModel interface (on Picture 3) and we are good to go.
To make this even more appealing: if we use an IoC container we only have to change the configuration in the container to start to use this other Model…

Here a listing of the Presenter of picture 2.

   1:  using System;
   2:  using Microsoft.Practices.Unity;
   3:  using HC.Interfaces.Zaak;
   4:  using HC.Mvp;
   5:  using HC.Domain;
   6:   
   7:  namespace HC.Presenters.Zaak
   8:  {
   9:      public class ZaakDetailPresenter: Presenter<IZaakDetailsView>, IZaakDetailsPresenter
  10:      {
  11:          private Zaak CurrentZaak{ get; set;}
  12:   
  13:          [Dependency]
  14:          public IZaakService Service { get; set;}
  15:   
  16:          private IZaakModel _model;
  17:          public ZaakDetailPresenter([Dependency] IZaakModel model)
  18:          {
  19:              _model = model;
  20:              _model.CurrentZaakChanged += new EventHandler<DataEventArgs<Zaak>>(_model_CurrentZaakChanged);
  21:          }
  22:   
  23:          void _model_CurrentZaakChanged(object sender, DataEventArgs<Zaak> e)
  24:          {
  25:              CurrentZaak = e.Data;
  26:              View.ShowCurrentZaakOnView(CurrentZaak);
  27:          }
  28:   
  29:          public override void OnViewInitialized()
  30:          {
  31:              base.OnViewInitialized();
  32:          }
  33:   
  34:          public override void OnViewLoaded()
  35:          {
  36:              View.ShowCurrentZaakOnView(CurrentZaak);
  37:          }
  38:   
  39:      }
  40:  }

Listing 1: Presenter

 

Because the Presenter (in listing 1) is derived from the Presenter<TView> abstract class, it is necessary to tell the Presenter of what type its View will be. Because we  use the Interface again, all we have to do is let Unity (our IoC container) do the work to supply the concrete implementation for this Interface. On line 13 of listing 1 we see the Dependency attribute, in this case the attribute will be used by Unity to resolve the concrete implementation of the IZaakService interface for the property (Service) on which the attribute is decorated that is configured.

The Model
The Model from picture 1 implements the Interface IZaakModel, and is responsible for getting the data if the Presenter asks for it and for letting the Presenter know that it has got this data and handing it over to the Presenter.

   1:  using System;
   2:  using Microsoft.Practices.Unity;
   3:  using HC.Domain;
   4:  using HC.Mvp;
   5:  using HC.Interfaces.Zaak;
   6:   
   7:  namespace HC.Models
   8:  {
   9:      public class ZaakModel : IZaakModel
  10:      {
  11:          public event EventHandler<DataEventArgs<Zaak>> CurrentZaakChanged;
  12:   
  13:          private IZaakService _datasource;
  14:          private Zaak _CurrentZaak;
  15:   
  16:          public ZaakModel([Dependency] IZaakService datasource)
  17:          {
  18:              _datasource = datasource;
  19:          }
  20:   
  21:          #region IZaakModel Members
  22:          public void LoadCurrentZaakById(int zaakId)
  23:          {
  24:              CurrentZaak = _datasource.GetZaakById(zaakId);
  25:          }
  26:   
  27:          public Zaak CurrentZaak
  28:          {
  29:              get { return _CurrentZaak; }
  30:              set
  31:              {
  32:                  _CurrentZaak = value;
  33:                  OnCurrentZaakChanged(new DataEventArgs<Zaak>(_CurrentZaak));
  34:              }
  35:          }
  36:   
  37:          public virtual void OnCurrentZaakChanged(DataEventArgs<ZaakExtended> e)
  38:          {
  39:              if (CurrentZaakChanged != null)
  40:                  CurrentZaakChanged(this, e);
  41:          }
  42:          #endregion
  43:      }   
  44:  }

Listing 2.: The Model

In listing 2 the Model is listed, is also depending on Unity for the resolving of the concrete implementations for interfaces. It implements IZaakModel  and thus implements the LoadCurrentZaakById method and the CurrentZaak property. When the  LoadCurrentZaakById (line 22, listing 2) is called it fills the CurrentZaak property calling a method on an object that implements the IZaakService interface (the private _datasource variable that is set by the ZaakModel constructor using Unity).

When the CurrentZaak property is filled the setter (line 30, listing 2) is used and in the setter the CurrentZaakChanged event is raised. Every object that subscribes to this event will recieve the change.

In listing 1 we can see on line 20 the Presenter has attached the event and will recieve this change. On line 26 of listing 1 the ShowCurrentZaakOnView method of the View is called.

The View
In ASP.NET a request will load an aspx page, the view is where the request starts, the view than delegates responsibility to the Presenter.

   1:  using System;
   2:  using Microsoft.Practices.Unity;
   3:  using HC.Interfaces.Zaak;
   4:  using HC.Mvp;
   5:  using HC.Domain;
   6:   
   7:  namespace HC.ZaakModule
   8:  {
   9:      public partial class ZaakDetails : System.Web.UI.UserControl,IZaakDetailsView
  10:      {
  11:          IZaakDetailsPresenter _presenter;
  12:          public event EventHandler UserControlLoaded;
  13:          [Dependency]
  14:          public IZaakDetailsPresenter Presenter
  15:          {
  16:              get
  17:              {
  18:                  return _presenter;
  19:              }
  20:              set
  21:              {
  22:                  if (value == null)
  23:                      throw new ArgumentNullException("value is null");
  24:              
  25:                  _presenter = value;
  26:                  _presenter.View = this;
  27:              }
  28:          }
  29:      
  30:          protected void Page_Load(object sender, EventArgs e)
  31:          {
  32:              if (!this.IsPostBack)
  33:              {
  34:                  this._presenter.OnViewInitialized();
  35:              }
  36:              this._presenter.OnViewLoaded();
  37:          }
  38:          
  39:          #region Control Init (Unity)
  40:          protected override void OnInit(EventArgs e)
  41:          {
  42:              IUnityContainer container = Container.Instance;
  43:              _presenter = container.Resolve<IZaakDetailsPresenter>();
  44:              _presenter.View = this;
  45:              base.OnInit(e);
  46:          }
  47:          #endregion
  48:      
  49:          #region IZaakDetailsView Members
  50:          public void ShowCurrentZaakOnView(Zaak zaak)
  51:          {
  52:              DetailsAlgemeenControl.CurrentZaak = zaak;
  53:              DetailsVoortgangControl.CurrentZaak = zaak;
  54:          }
  55:          #endregion
  56:      }
  57:  }

Listing 3.: The View

On line 50 of listing 3 the OnInit method of the UserControl (our view) is listed. Inside the body of this method we can see that we instantiate a variable named container (type IUnityContainer) and put a Container.Instance in it. On the next line (line 53) we fill the private member _presenter (the private member that is used in our property Presenter) by letting the container resolve the interface  IZaakDetailsPresenter. On the next line (line 54) we tell the Presenter that it’s View is this control. We have to do this here, because the View is where the request comes in. So this is the first component of our App that is loaded. Because my requirement is to create modules that can be used in Sharepoint or in ASP.NET, I cannot use the Global.asax to resolve the concrete implementations.

The ascx, or html is very straightforward, so i am not showing it, because I feel it is in the way of what i want to tell. I hope it is clear enough without it.

The Container
So how can
the container variable that is of Type IUnityContainer, an interface, on line 52 know what concrete class to Resolve? and where does Container come from. What does Container.Instance do?
In a class called container I create a UnityContainer using the Singleton design pattern:

   1:  using System;
   2:  using Microsoft.Practices.Unity;
   3:  using HC.Models;
   4:  using HC.Interfaces.Zaak;
   5:  using HC.Services;
   6:  using HC.Presenters.Zaak;
   7:   
   8:  namespace HC.ZaakModule
   9:  {
  10:      public class Container
  11:      {
  12:   
  13:          private static IUnityContainer instance;
  14:   
  15:          private Container() { }
  16:   
  17:          public static IUnityContainer Instance
  18:          {
  19:              get
  20:              {
  21:                  if (instance == null)
  22:                  {
  23:                      instance = new UnityContainer();
  24:   
  25:                      instance.RegisterType<IZaakModel, ZaakModel>(new ContainerControlledLifetimeManager())
  26:                          .RegisterType<IZaakService, ZaakService>()
  27:                          .RegisterType<IZaakView, Zaken>()
  28:                          .RegisterType<IZaakPresenter, ZaakPresenter>()
  29:                          .RegisterType<IZaakListView, ZaakList>()
  30:                          .RegisterType<IZaakSearchPresenter, ZaakSearchPresenter>()
  31:                          .RegisterType<IZaakSearchView, ZaakSearch>()
  32:                          .RegisterType<IZaakListPresenter, ZaakListPresenter>()
  33:                          .RegisterType<IZaakDetailsView, ZaakDetails>()
  34:                          .RegisterType<IZaakDetailsPresenter, ZaakDetailPresenter>();
  35:                  }
  36:                  return instance;
  37:              }
  38:          }
  39:      }
  40:  }

Listing 4.: The Container

 

Singleton
Using the singleton design pattern
the registering of the concrete implementation to the interfaces will be done only once, as you can see in the module I am building there are more components that follow the same pattern, so using a singleton was in my opinion the way to go in this case.
I choose to use a simple version of the singleton, I make a class called container, this class has a private static variable called instance (of type IUnityContainer).
The class has a private constructor, so the class cannot be directly created. Furthermore the class has a public static property (type IUnityContainer) that can only get a single instance of a IUnityContainer, because in the getter we check if the private member called instance (type IUnityContainer) is null or has been filled already, if it is filled the instance it contains is returned, but if it is null a new UnityContainer is instantiated and using a Fluent Interface all Interfaces and their concrete implementations are registered inside it before we pass it to the instance variable, after that the instance it contains is returned.

On line 25 of listing 4 the RegisterType has a parameter and the following RegisterType methods of the fluent interface have not. With new ContainerControlledLifeManager() as a parameter into the RegisterType method we tell Unity to resolve the concrete implementation as a singleton. In the case of the Model I need it to be a singleton, because the model is the only place some state need to be held in my architecture.

Configuration file
Configuring the registration in a  configuration file is also possible, in my case I did not wanted to do it, but I can understand that in some cases that is exactly what you want.

Conclusion
Ofcourse a lot more has to be considered when using this architecture, but I hope this article helps in understanding how you can use Dependency injection or Inversion of control and the Model view Presenter pattern to create maintainable and robust applications.

Henry Cordes
My thoughts exactly…


SDN Article on MVC Framework

Published 3/9/2009 by Henry in ASP.NET | C#
Tags: ,

My article (in dutch) with the title: ASP.NET Webapplications finally unit-testable, or (ASP.NET webapplicaties eindelijk unit-testbaar in dutch) is been published in the 100th edition of the SDN Magazine (Software Developers Network). SDN 100th Magazine in pdf format and is available for download.

VP100100th SDN Magazine

Henry Cordes
My thoughts exactly…


I am in the middle of the analysis fase for the project I mentioned in the post about using WCSF for ASP.NET (and Sharepoint) Usercontrols.  I know how I am going to integrate the UserControls into SharePoint in such a way, that the controls can be used in SharePoint and in custom ASP.NET Web applications.
I am going to use the MVP pattern without the help of WCSF or CWAB, but with the help of Unity. I will post an article in more detail about this in the near future.
For now I want to share a simple ASP.NET composite control I need, to make it easier to have watermark functionality for every textbox on a page, without having to add a TextBoxWatermarkExtender for every TextBox.

The way I accomplish this is by creating a composite control with a TextBox and a TextboxWatermarkExtender on it.

The code:

   1:  using System;
   2:  using System.ComponentModel;
   3:  using System.Web.UI;
   4:  using System.Web.UI.WebControls;
   5:  using AjaxControlToolkit;
   6:   
   7:  namespace HC.Web.Controls
   8:  {
   9:   
  10:       [DefaultProperty("Text"),
  11:        ValidationProperty("Text"),
  12:        Description("TextBox with Watermark capabilities"),
  13:        ToolboxData("<{0}:WatermarkTextBox runat=server></{0}:WatermarkTextBox>")]
  14:      public class WatermarkTextBox: CompositeControl
  15:      {
  16:          #region Private members
  17:           private TextBox textBox;
  18:           private TextBoxWatermarkExtender watermarkExtender;
  19:   
  20:           private string _DefaultWatermarkText = "Watermark";
  21:          #endregion
  22:   
  23:          #region Properties
  24:           /// <summary>
  25:           /// Gets the ClientID of the textbox
  26:           /// </summary>
  27:          [Bindable(true),
  28:          Category("Behavior"),
  29:          Description("The TextBoxClientID of the WatermarkTextBox"),
  30:          DefaultValue("")]
  31:          public string TextBoxClientID
  32:           {
  33:               get
  34:               {
  35:                   EnsureChildControls();
  36:                   return textBox.ClientID;
  37:               }
  38:           }
  39:   
  40:           /// <summary>
  41:           /// Gets or sets the Text in the textbox
  42:           /// </summary>
  43:           [Bindable(true),
  44:          Category("Behavior"),
  45:          Description("The text of the textbox"),
  46:          DefaultValue("")]
  47:           public string Text
  48:           {
  49:               get
  50:               {
  51:                   EnsureChildControls();
  52:                   return textBox.Text;
  53:               }
  54:               set
  55:               {
  56:                   EnsureChildControls();
  57:                   textBox.Text = value;
  58:               }
  59:           }
  60:   
  61:           /// <summary>
  62:           /// Gets or sets the CssClass of the Textbox
  63:           /// </summary>
  64:           [Bindable(true),
  65:           Description("The css class that is used when the textbox is in it's normal state"),
  66:           Category("Appearance"),
  67:           DefaultValue("")]
  68:           public override string CssClass
  69:           {
  70:               get
  71:               {
  72:                   EnsureChildControls();
  73:                   return textBox.CssClass;
  74:               }
  75:               set
  76:               {
  77:                   EnsureChildControls();
  78:                   textBox.CssClass = value;
  79:               }
  80:           }
  81:   
  82:           /// <summary>
  83:           /// Gets or sets the CssClass for the watermark state of the Textbox
  84:           /// </summary>
  85:           [Bindable(true),
  86:            Description("The css class that is used when the textbox is in it's watermark state"),
  87:            Category("Appearance"),
  88:            DefaultValue("")]
  89:           public string WatermarkCssClass
  90:           {
  91:               get 
  92:               { 
  93:                   EnsureChildControls();
  94:                   return watermarkExtender.WatermarkCssClass;
  95:               }
  96:               set 
  97:               { 
  98:                   EnsureChildControls();
  99:                   watermarkExtender.WatermarkCssClass = value;
 100:               }
 101:           }
 102:   
 103:           /// <summary>
 104:           /// Gets or sets the Text for the watermark
 105:           /// </summary>
 106:          [Bindable(true),
 107:           Category("Appearance"), 
 108:           Description("The (watermark)text that is shown when the textbox is in it's watermark state"),
 109:           DefaultValue("")]
 110:          public string WatermarkText 
 111:          {
 112:               get 
 113:               { 
 114:                   EnsureChildControls();
 115:                   return watermarkExtender.WatermarkText;
 116:               }
 117:               set 
 118:               { 
 119:                   EnsureChildControls();
 120:                   watermarkExtender.WatermarkText = value;
 121:               }
 122:          }
 123:   
 124:           /// <summary>
 125:           /// Gets or sets DefaultWatermarkText, cannot be empty
 126:           /// </summary>
 127:          [Bindable(true),
 128:          Category("Appearance"),
 129:          Description("The default (watermark)text that is shown when the textbox is in it's watermark state, and the WatermarkText property is empty"),
 130:          DefaultValue("")]
 131:          public string DefaultWatermarkText
 132:          {
 133:              get { return _DefaultWatermarkText; }
 134:              set 
 135:              { 
 136:                  if (value.Length > 0)
 137:                      _DefaultWatermarkText = value; 
 138:              }
 139:          }
 140:          #endregion
 141:   
 142:          protected override void RecreateChildControls()
 143:          {
 144:              EnsureChildControls();
 145:          }
 146:   
 147:          protected override void CreateChildControls()
 148:          {
 149:              SetTextBoxIdIfEmpty();
 150:              this.Controls.Add(textBox);
 151:              watermarkExtender.ID = textBox.ID + "_waterMarkExtender";
 152:              watermarkExtender.TargetControlID = textBox.ID;
 153:   
 154:              if (WatermarkText == "")
 155:              {
 156:                  WatermarkText = DefaultWatermarkText;
 157:              }
 158:              this.Controls.Add(watermarkExtender);
 159:          }
 160:   
 161:          #region Worker Methods
 162:          /// <summary>
 163:          /// Fills textBox ID if empty.
 164:          /// Format: ID + '_textBox'
 165:          /// </summary>
 166:           private void SetTextBoxIdIfEmpty()
 167:          {
 168:              if (string.IsNullOrEmpty(textBox.ID))
 169:              {
 170:                  textBox.ID = this.ID + "_textBox";
 171:              }
 172:          }
 173:          #endregion
 174:        
 175:           #region C'tor
 176:           public WatermarkTextBox()
 177:           {
 178:               textBox = new TextBox();
 179:               watermarkExtender = new TextBoxWatermarkExtender();
 180:           }
 181:           #endregion
 182:   
 183:      }
 184:  }

Listing: 1

As you can see in the code in listing 1,in the override of the CreateChildControls the actual adding of the controls to the control collection of the composite container is done.
It is important to make sure the textbox has a valid ID. Than you need to set the TargetControlID of the TextboxWatermarkExtender equal to the ID of the TextBox and the WatermarkText needs to be filled.

EnsureChildControls()
When you built a composite control make sure to call EnsureChildControls, so you can be sure the controls are accesible and no object reference not set exception is thrown.
A simple but quite useful example.

Henry Cordes
My thoughts exactly…