Design Patterns

ASP.NET MVC and Kendo UI Grid

0

A grid provides a common presentation to represent a collection of data, which is a table containing rows and columns. Although creating this experience is not difficult, the features to deliver a quality user experience will require a significant investment. The alternative is a widget library, which provides advanced features requiring minimal effort.

In this post, I will demonstrate a few features of the Kendo UI Grid, which is one of many widgets included in the Kendo UI products. After several years of experience with Telerik products, the next generation Kendo UI is HTML5 and CSS3. I also elected to include the Kendo UI Complete, which packages convenient server extensions for the JavaScript framework. You can learn more about the products and better understand the licensing, which is a huge obstacle for many budget conscious organization. And yes…many alternatives exist including the JQuery.UI library.

Kendo UI provides a handy Visual Studio plugin, which can convert and prepare projects for Kendo UI. I converted an existing ASP.NET MVC4 project, which saves several manual steps. I was also able to select one of the Kendo themes, which will be applied to all Kendo widgets.

You can read several of my previous posts, which discuss design patterns to build enterprise applications. In this article, my goal is to provide a quick start for the Kendo UI Grid implementation. So…I will not create a fully functioning repository, but instead a static memory based to provide the basics for the demonstration.

I will modify the standard ASP.NET MVC4 starter project and add a new menu option called Contacts. This will require a controller, view model and service - all the basics. We’ll start with a simple read-only grid, which will display the current contacts with paging, filtering and sorting features. The following is the read-only Contacts grid.

Contacts Read-Only Grid

The grid is a table containing the Name, Mode of Contact, Phone and Email columns. The sort, filter and paging features are enabled, so the user can interact with the grid and data using several helpful options. So…let’s look at the view containing the grid configuration.

 C# |  copy code |? 
01
@using MvcKendoUIGrid.Models
02
 
03
@(Html.Kendo().Grid<Contact>()
04
      .Name("contactGrid")
05
      .Columns(columns =>
06
 
07
          {
08
               columns.Bound(c => c.Name).Title("Name").Width(150);
09
              columns.Bound(c => c.PreferredContactMode).Title("Mode of Contact").Width(150);
10
              columns.Bound(c => c.Phone).Title("Phone").Width(120);
11
              columns.Bound(c => c.Email).Title("Email").Width(120);
12
          })
13
      .Pageable()
14
      .Filterable()
15
      .Sortable()
16
      .Scrollable()
17
      .AutoBind(true)
18
      .HtmlAttributes(new {style = "height:250px;"})
19
      .DataSource(dataSource => dataSource
20
                                    .Ajax()
21
                                    .ServerOperation(false)
22
                                    .Model(model =>
23
                                        {
24
                                            model.Id(c => c.Id);
25
                                            model.Field(c => c.PreferredContactMode).Editable(true).DefaultValue(new ContactMode {Id = 0, Name = string.Empty});
26
                                        })
27
                                    .Read(read => read.Action("Read", "Contact"))
28
)      )

The Pageable, Sortable, Filterable and Scrollable provide the advanced grid features with just one line of code. The DataSource defines the data and actions to read. The model is the Contact, so the fields and id are defined. The Read action is an ajax call to the Contact controller and Read method, which will return a collection of Contact objects. The Columns define the layout of columns, headers and binding to the model.

The Contact model contains the Id, NamePhone and Email properties. It also includes the ContactMode, which is a complex object including an Id and Name. We’ll see more on the complex object in the next section.

 C# |  copy code |? 
01
using System.Collections.Generic;
02
using System.Web.Mvc;
03
using Kendo.Mvc.Extensions;
04
using Kendo.Mvc.UI;
05
using MvcKendoUIGrid.Models;
06
using MvcKendoUIGrid.Services;
07
 
08
namespace MvcKendoUIGrid.Controllers
09
{
10
    /// <summary>
11
    /// Contact controller providing support for views
12
    /// </summary>
13
    public class ContactController : Controller
14
    {
15
        private readonly IContactService _service;
16
 
17
        /// <summary>
18
        /// Default Constructor
19
        /// </summary>
20
        public ContactController()
21
        {
22
            _service = new ContactService();
23
        }
24
 
25
        /// <summary>
26
        /// Default action to render Contact grid
27
        /// </summary>
28
        /// <returns></returns>
29
        public ActionResult Index()
30
        {
31
            TempData["ContactMode"] = new List<ContactMode>
32
                {
33
                    new ContactMode {Id = 1, Name = "Phone"},
34
                    new ContactMode {Id = 2, Name = "Email"}
35
                };
36
 
37
            return View();
38
        }
39
 
40
        /// <summary>
41
        ///     Read action to populate grid
42
        /// </summary>
43
        /// <param name="dsRequest">Kendo Datasource Request</param>
44
        /// <returns>ActionResult</returns>
45
        [HttpPost]
46
        public ActionResult Read([DataSourceRequest] DataSourceRequest dsRequest)
47
        {
48
            try
49
            {
50
                return Json(_service.GetAllContacts().ToDataSourceResult(dsRequest));
51
            }
52
            catch
53
            {
54
                ModelState.AddModelError("Contacts", "Unable to load contacts.");
55
                return Json(ModelState.ToDataSourceResult());
56
            }
57
        }
58

The Index action is called on the initially, which will save the possible ContactMode selections as TempData. The Read action invokes the service GetAllContacts method to return a collection of Contacts.

The next step is providing the ability to edit the contacts. The following is the revised view, which includes the changes to enable editing.

 C# |  copy code |? 
01
@using MvcKendoUIGrid.Models
02
 
03
@(Html.Kendo().Grid<Contact>()
04
      .Name("contactGrid")
05
      .Columns(columns =>
06
 
07
          {
08
              columns.Command(command =>
09
                  {
10
                      command.Edit();
11
                   }).Width(180);
12
              columns.Bound(c => c.Name).Title("Name").Width(150);
13
              columns.Bound(c => c.PreferredContactMode).Title("Mode of Contact").Width(150);
14
              columns.Bound(c => c.Phone).Title("Phone").Width(120);
15
              columns.Bound(c => c.Email).Title("Email").Width(120);
16
          })
17
      .Pageable()
18
      .Filterable()
19
      .Sortable()
20
      .Scrollable()
21
      .AutoBind(true)
22
      .HtmlAttributes(new {style = "height:250px;"})
23
      .Editable(ed => ed.Mode(GridEditMode.InLine))
24
      .DataSource(dataSource => dataSource
25
                                    .Ajax()
26
                                    .ServerOperation(false)
27
                                    .Model(model =>
28
                                        {
29
                                            model.Id(c => c.Id);
30
                                            model.Field(c => c.PreferredContactMode).Editable(true).DefaultValue(new ContactMode {Id = 0, Name = string.Empty});
31
                                        })
32
                                    .Read(read => read.Action("Read", "Contact"))
33
                                    .Update(update => update.Action("Edit", "Contact"))
34
      )
35
      )

The DataSource now includes the Update, which calls the Contact controller Edit method. The Editable supports inline and popup edit modes, so we will select inline to allow editing within the grid. We also add a column command, which injects the edit button in the first column. We also add the Edit method to the controller, which is responsible for calling the service to update the contract.

 C# |  copy code |? 
01
        /// <summary>
02
        /// Edit action to update existing contact
03
        /// </summary>
04
        /// <param name="dsRequest">Kendo Datasource Request</param>
05
        /// <param name="viewmodel">Contact model containing values to update</param>
06
        /// <returns>ActionResult</returns>
07
        [HttpPost]
08
        public ActionResult Edit([DataSourceRequest] DataSourceRequest dsRequest, Contact viewmodel)
09
        {
10
            try
11
            {
12
                if (ModelState.IsValid && viewmodel != null)
13
                    _service.Update(viewmodel);
14
                else //model error
15
                    ModelState.AddModelError("Contacts", "Unable to edit contact - not a valid contact.");
16
            }
17
            catch
18
            {
19
                ModelState.AddModelError("Contacts", "Unable to edit contact.");
20
            }
21
 
22
            return Json(ModelState.ToDataSourceResult());
23
        }
24

If we test the changes then we see the addition of the edit button. Clicking the edit button will allow the editing of the selected row.

Contact Grid Edit

You will notice the Mode of Contact column displays the Id and Name textbox, which is not the best experience for selecting the contact mode.

Contact Grid Edit Complex Object

Since ContactMode is a complex object, the editor includes the Id and Name. We would like to provide a dropdown list of available contact modes, so the user must select a valid option. We previously saved a collection of ContactMode objects representing the valid options in the TempData, so this will be the dropdown list source. The solution is creating a new editor for the ContactMode type, so when the correct editor is presented. The following is the ContactMode editor, which should be added to the Shared Editor Templates folder.

 C# |  copy code |? 
1
@model MvcKendoUIGrid.Models.ContactMode
2
@(Html.Kendo().DropDownList()
3
      .Name("PreferredContactMode")
4
      .BindTo((System.Collections.IEnumerable)TempData["ContactMode"])
5
      .OptionLabel("Select a Mode")
6
      .DataTextField("Name")
7
      .DataValueField("Id")
8
      .HtmlAttributes(new { required = true })
9
      )

We are using the Kendo UI DropDownList widget, which is a dropdown list. The BindTo is the list data source, which is referencing the TempData we populated in our initial Index method. The DataTextField and DataValueField are the value and text property names. We also set the required attribute, which ensures the contact mode is required. It is important to note the Name must be the name of the grid model property, so the two-way binding is correct. Let’s see the results of the changes to the edit mode.

Contacts Grid Edit Dropdown

The final features are Add and Delete. The following is the view containing the updates for Add and Delete. You will also notice the ClientTemplate applied to the ContactMode, which forces the view to include the Name property in the display.

 C# |  copy code |? 
01
@using MvcKendoUIGrid.Models
02
 
03
@(Html.Kendo().Grid<Contact>()
04
      .Name("contactGrid")
05
      .Columns(columns =>
06
 
07
          {
08
              columns.Command(command =>
09
                  {
10
                      command.Edit();
11
                      command.Destroy();
12
                  }).Width(180);
13
              columns.Bound(c => c.Name).Title("Name").Width(150);
14
              columns.Bound(c => c.PreferredContactMode).Title("Mode of Contact").ClientTemplate("#=PreferredContactMode.Name#").Width(150);
15
              columns.Bound(c => c.Phone).Title("Phone").Width(120);
16
              columns.Bound(c => c.Email).Title("Email").Width(120);
17
          })
18
      .ToolBar(toolbar => toolbar.Create().Text("Add new contact"))
19
      .Pageable()
20
      .Filterable()
21
      .Sortable()
22
      .Scrollable()
23
      .AutoBind(true)
24
      .HtmlAttributes(new {style = "height:250px;"})
25
      .Editable(ed => ed.Mode(GridEditMode.InLine))
26
      .DataSource(dataSource => dataSource
27
                                    .Ajax()
28
                                    .ServerOperation(false)
29
                                    .Model(model =>
30
                                        {
31
                                            model.Id(c => c.Id);
32
                                            model.Field(c => c.PreferredContactMode).Editable(true).DefaultValue(new ContactMode {Id = 0, Name = string.Empty});
33
                                        })
34
                                    .Read(read => read.Action("Read", "Contact"))
35
                                    .Update(update => update.Action("Edit", "Contact"))
36
                                    .Destroy(delete => delete.Action("Delete", "Contact"))
37
                                    .Create(create => create.Action("Create", "Contact"))
38
      )
39
      )

We add the Destroy to the command, which provides the Delete button. The DataSource Destroy defines the Contact controller delete action, which will be responsible for deleting the contact. We add the create command to the Toolbar, which is positioned above the grid. The DataSource Create is the action invoked when the “Add new contact” button is clicked.

The Create and Delete controller methods appear below.

 C# |  copy code |? 
01
        /// <summary>
02
        /// Create action to add new contact
03
        /// </summary>
04
        /// <param name="dsRequest">Kendo Datasource Request</param>
05
        /// <param name="viewmodel">Contact model containing values to add</param>
06
        /// <returns>ActionResult</returns>
07
        [HttpPost]
08
        public ActionResult Create([DataSourceRequest] DataSourceRequest dsRequest, Contact viewmodel)
09
        {
10
            try
11
            {
12
                if (ModelState.IsValid && viewmodel != null)
13
                {
14
                    _service.Add(viewmodel);
15
                    return Json(new[] {viewmodel}.ToDataSourceResult(dsRequest, ModelState));
16
                }
17
                ModelState.AddModelError("Contacts", "Unable to add contact - not a valid contact.");
18
            }
19
            catch
20
            {
21
                ModelState.AddModelError("Contacts", "Unable to add contact.");
22
            }
23
 
24
            return Json(ModelState.ToDataSourceResult());
25
        }
26
 
27
        /// <summary>
28
        /// Delete action to remove existing contact
29
        /// </summary>
30
        /// <param name="dsRequest">Kendo Datasource Request</param>
31
        /// <param name="viewmodel">Contact model containing values to delete</param>
32
        /// <returns>ActionResult</returns>
33
        [HttpPost]
34
        public ActionResult Delete([DataSourceRequest] DataSourceRequest dsRequest, Contact viewmodel)
35
        {
36
            try
37
            {
38
                if (viewmodel != null)
39
                    _service.Delete(viewmodel);
40
                else
41
                    ModelState.AddModelError("Contacts", "Unable to delete contact - not a valid contact.");
42
            }
43
            catch
44
            {
45
                ModelState.AddModelError("Contacts", "Unable to delete contact.");
46
            }
47
 
48
            return Json(ModelState.ToDataSourceResult());
49
        }
50

The final version with the Edit, Add and Delete actions enabled.

Contacts Grid Complete

Contacts Grid AddContacts Grid Delete

I hope this provides a quick overview of the Kendo UI Grid widget and Kendo UI MVC server extensions, which together provide powerful features with minimal effort.

Castle Windsor IoC and AOP with ASP.NET MVC 4

0

It is no secret that I am a huge supporter of IoC (Inversion of Control) and AOP (Aspect-oriented Programming), which is evident with several earlier posts focused on building Enterprise applications. My first IoC experience was a Java portal project, which implemented Spring for many enterprise services. My recent projects have been .NET, which include several Spring.NET and Castle implementations. When evaluating IoC products, Ninject and more recently Microsoft Unity have also been candidates. IoC is gaining Microsoft community acceptance, especially with the release of ASP.NET MVC 4 and improved support/integration. See previous article for more information on design patterns including Dependency Injection (DI), Single Responsibility Principle (SRP) and Separation of Concerns (SoC).

In this post, I will provide an overview of the MVC 4 Castle Windsor IoC and Castle Core Dynamic Proxy features. Gasp…after several articles and posts with Spring.NET? This is true, but every project should evaluate several IoC (also referred to as Dependency Injection) containers and select the one that fits.

I would recommend NuGet for packages, so you can simplify the management of 3rd party libraries and tools.

Once you create a new ASP.NET MVC 4 solution and add the Castle packages to your solution, we can start building the application framework and scaffolding. Since this is a quick-start for Castle IoC and AOP features, we’ll build the essential components for a working MVC 4 solution.

First, create a Framework folder for the IoC and AOP classes. I would recommend Framework or Core, which are descriptive names. I created a Windsor sub-folder, which indicates the items will be supporting the IoC and AOP. The next level is Installers and Interceptors at the same level, so the following is an example of the project structure.

Framework Folder Structure

First, we will create the boilerplate WindsorControllerFactory to handle the IoC plumbing. The following is a snippet of the code, which you can add to the Framework.Windsor folder.

01
using System;
02
using System.Web;
03
using System.Web.Routing;
04
using Castle.MicroKernel;
05
using System.Web.Mvc;
06
 
07
namespace Mvc4Castle.Framework.Windsor
08
{
09
    /// <summary>
10
    /// Castle Windsor MVC4 Controller Factory Implementation for IoC
11
    /// </summary>
12
    public class WindsorControllerFactory : DefaultControllerFactory
13
    {
14
        private IKernel _kernel;
15
 
16
        public WindsorControllerFactory(IKernel kernel)
17
        {
18
            _kernel = kernel;
19
        }
20
 
21
        public override void ReleaseController(IController controller)
22
        {
23
            _kernel.ReleaseComponent(controller);
24
        }
25
 
26
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
27
        {
28
            if (controllerType == null)
29
            {
30
                throw new HttpException(404, string.Format("The Windsor Controller at path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
31
            }
32
            return (IController)_kernel.Resolve(controllerType);
33
        }
34
    }
35
}

Next, we will create IWindsorInstaller implementations. The installers will register components or objects with the IoC container. Alternatively, you can choose XML-based configuration files to define the components/objects instructing the container on the “How” to instantiate. In our example, we will use the MVC controllers included in the starter project (e.g. HomeController).

01
using Castle.MicroKernel.Registration;
02
using Castle.Windsor;
03
using Castle.MicroKernel.SubSystems.Configuration;
04
using System.Web.Mvc;
05
using Mvc4Castle.Controllers;
06
 
07
namespace Mvc4Castle.Framework.Windsor.Installers
08
{
09
    /// <summary>
10
    /// Castle Windsor Controller responsible for registering classes managed by
11
    /// the IoC container.
12
    /// 
13
    /// This implementation registers all MVC Controllers (IController).
14
    /// </summary>
15
    public class ControllerInstaller : IWindsorInstaller
16
    {
17
        public void Install(IWindsorContainer container, IConfigurationStore store)
18
        {
19
            container.Register(Classes.FromThisAssembly()
20
                                .BasedOn<IController>()
21
                                .LifestyleTransient()
22
                                .ConfigureFor<HomeController>(c => c.DependsOn(Dependency.OnComponent("service", "MyServiceResource"))));
23
        }
24
    }
25
}

In this example, we are registering objects/components based on IController located in the current assembly. We are also configuring the HomeController and dependency injection of the service argument. We’ll explore additional options for registering objects/components in the container.

We also need to add the container to our start-up processes in the global.asax. The Application_Start and Application_End require some logic to handle this task.

01
    public class MvcApplication : System.Web.HttpApplication
02
    {
03
        private static IWindsorContainer _container;
04
 
05
        protected void Application_Start()
06
        {
07
            AreaRegistration.RegisterAllAreas();
08
 
09
            WebApiConfig.Register(GlobalConfiguration.Configuration);
10
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
11
            RouteConfig.RegisterRoutes(RouteTable.Routes);
12
            BundleConfig.RegisterBundles(BundleTable.Bundles);
13
            InjectContainer();
14
        }
15
 
16
        /// <summary>
17
        /// Create MVC4 Controller for Castle Windsor IoC container
18
        /// </summary>
19
        private static void InjectContainer()
20
        {
21
            _container = new WindsorContainer().Install(FromAssembly.This());
22
 
23
            var controllerFactory = new WindsorControllerFactory(_container.Kernel);
24
            ControllerBuilder.Current.SetControllerFactory(controllerFactory);
25
        }
26
 
27
        /// <summary>
28
        /// Destroy Castle Windsor IoC container
29
        /// </summary>
30
        protected void Application_End()
31
        {
32
            _container.Dispose();
33
        }
34
    }
35

You can add several installer implementations using the fluent API or XML-based configuration files, so you can organize your object/component definitions for the IoC container. Since we are following design patterns, we will introduce Dependency Injection/DIP practices to inject the object/component dependency via the controller constructor. The service will represent the business logic, which is responsible for orchestrating the calls to the data tier or other service objects to process the client request and return an appropriate result.

1
       private IService _service;
2
 
3
        public HomeController(IService service)
4
        {
5
            _service = service;
6
        }

So…let’s take a look at a few container registration options. The following will register all objects/components with a type ending in “Service” (i.e. wildcard Service) from the current assembly. The life-cycle can also be configured, which in the examples ”transient” indicates a new instance.

1
           container.Register(Classes.FromThisAssembly()
2
                 .Where(type => type.Name.EndsWith("Service"))
3
                 .WithServiceDefaultInterfaces()
4
                 .Configure(c => c.LifestyleTransient().Interceptors<ServiceTitleInterceptor>()));
5

We’ll cover the AOP or dynamic proxies, which is the Interceptor. The following example defines the dependency using a named value, so the “Title” property will be set to the static value “Injected By Dependency Value”.

1
            container.Register(Component.For<IService>()
2
                .ImplementedBy<HomeService>()
3
                .Named("MyServiceValue")
4
                .DependsOn(Dependency.OnValue("Title", "Injected By Dependency Value"))
5
                .LifestyleTransient());
6

The next example is injecting the “Title” property value from the web.config appsettings “Title” parameter.

1
            container.Register(Component.For<IService>()
2
                .ImplementedBy<HomeService>()
3
                .Named("MyServiceConfig")
4
                .DependsOn(Dependency.OnAppSettingsValue("Title", "Title"))
5
                .LifestyleTransient());
6

The following illustrates injecting a property value from a resource file, which also is the “Title” property. This provides several source options for the dependency injection, which can also include a named component (see Named).

1
            container.Register(Component.For<IService>()
2
                .ImplementedBy<HomeService>()
3
                .Named("MyServiceResource")
4
                .DependsOn(Dependency.OnResource<App_LocalResources.Resource1>("Title", "Title"))
5
                .LifestyleTransient());
6

The previous examples introduce the Castle Windsor IoC basics as they apply to MVC4. The last topic is AOP, which we encountered with the interceptor in a previous object/component container registration. The Spring.NET AOP support was introduced in a previous post. Castle core is a lighter version, which is based on implementing the Castle.DynamicProxy.IInterceptor.

01
    public class ServiceTitleInterceptor : IInterceptor
02
    {
03
        public void Intercept(IInvocation invocation)
04
        {
05
            if (invocation.Method.Name.Equals("get_Title"))
06
                invocation.ReturnValue = "You have been hijacked at." + DateTime.Now;
07
            else
08
                invocation.Proceed();
09
        }
10
     }

In this interceptor implementation, the Intercept method contains logic to check for the method name “get_Title”. This is a Title property getter. If true then ReturnValue is set to “You have been hijacked at.” including a date-stamp. If the method name is not “get_Title” then the control is returned to the intercepted object and processing continues. You can implement an interceptor for logging, caching, transaction management, error handling and other common services without adding code to every class and method.

The following is an installer snippet for registering an object/component using the ServiceTitleInterceptor interceptor, so every call will be intercepted and the Intercept method executed.

1
.Interceptors<ServiceTitleInterceptor>()

The above will apply the ServiceTitleInterceptor to the object/component. You can also add the InterceptorAttribute ( [Interceptor(typeof(ServiceTitleInterceptor))] ) to the target class, which is an alternative to the fluent API approach above.

01
using Castle.Core;
02
using Mvc4Castle.Framework.Windsor.Interceptors;
03
 
04
namespace Mvc4Castle.Framework.Services
05
{
06
    [Interceptor(typeof(ServiceTitleInterceptor))]
07
    public class HomeService : IService
08
    {
09
        public string Title { get; set; } 
10
    }
11
}

I hope this quick-start provides another IoC and AOP option for your MVC projects. Since I was evaluating several IoC libraries for a current project, I thought a summary could be helpful.

Related Posts:

Sping.NET IoC

Spring.NET and MVC3

Spring.NET AOP

Building Enterprise Frameworks – Testing and Mock Objects

0

This is the third installment of the “Building Enterprise Frameworks” series, which is the evolving design of an enterprise framework. In the series introduction, we presented a problem faced by many enterprise software teams and delivered a plan. The previous blog entry introduced the preliminary data access layer and domain model, which are a collection of abstractions forming a unified framework or infrastructure. In this blog entry, we refactor the data access layer and build the supporting unit tests.

Before covering testing, we will refactor the Repository introduced in the previous installment. At this time, we will eliminate the RepositoryBase abstract class. After testing and coding additional NHibernateRepositoryBase features, this class provided no immediate value to the enterprise framework. The abstract class was moved to the Framework Repository folder, which was vacated by the previous RepositoryBase. We also refactored the Generic interfaces and classes, which better aligns with our technical design and objectives. The following is the revised Framework project structure.

The following is the IRepository interface, which defines the required Repository implementation methods. As discussed in the previous installment, these are the basic Create-Read-Update-Delete (CRUD) operations.

01
using System;
02
using System.Collections.Generic;
03
using Joemwalton.Framework.Domain;
04
 
05
namespace Joemwalton.Framework.Data.Repository
06
{
07
    public interface IRepository<TEntity, TId>
08
        where TEntity : IEntity<TId>
09
    {
10
        void Save(TEntity entity);
11
        void Remove(TEntity entity);
12
        TEntity FindById(TId id);
13
        List<TEntity> FindAll();
14
    }
15
}

Since we eliminated the RepositoryBase abstract class, the NHibernateRepositoryBase will replace the method implementation for our NHibernate base class. The next installment of the “Building Enterprise Frameworks” series will focus on NHibernate and IoC, so the details of the design will not be discussed here – including session and transaction management. The base class will include the CRUD method implementation, so the concrete Repository implementations remain focused on providing domain specific data services. Basically…eliminating redundant code!

01
using System;
02
using System.Collections.Generic;
03
using NHibernate;
04
using NHibernate.Criterion;
05
using Joemwalton.Framework.Data.Repository;
06
using Joemwalton.Framework.Domain;
07
 
08
namespace Joemwalton.Framework.Data.NHibernate
09
{
10
    public abstract class NHibernateRepositoryBase<TEntity, TId> 
11
        : IRepository<TEntity, TId>
12
        where TEntity : IEntity<TId>
13
    {
14
        private ISessionFactory _sessionFactory;
15
 
16
        /// <summary>
17
        /// NHibernate Session Factory
18
        /// </summary>
19
        public ISessionFactory SessionFactory
20
        {
21
            protected get { return _sessionFactory; }
22
            set { _sessionFactory = value; }
23
        }
24
 
25
        /// <summary>
26
        /// Get current active session
27
        /// </summary>
28
        protected ISession CurrentSession
29
        {
30
            get { return this.SessionFactory.GetCurrentSession(); }
31
        }
32
 
33
        public TEntity FindById(TId id)
34
        {
35
            return this.CurrentSession.Get<TEntity>(id);
36
        }
37
 
38
        public List<TEntity> FindAll()
39
        {
40
            ICriteria query = this.CurrentSession.CreateCriteria(typeof(TEntity));
41
            return (List<TEntity>)query.List<TEntity>();
42
        }
43
 
44
        public void Save(TEntity entity)
45
        {
46
            using (ITransaction transaction = this.CurrentSession.BeginTransaction())
47
            {
48
                this.CurrentSession.SaveOrUpdate(entity);
49
                transaction.Commit();
50
            }
51
        }
52
 
53
        public void Remove(TEntity entity) 
54
        {
55
            using (ITransaction transaction = this.CurrentSession.BeginTransaction())
56
            {
57
                this.CurrentSession.Delete(entity);
58
                transaction.Commit();
59
            }
60
        }
61
    }
62
}

We are finished with the refactoring, so our attention shifts to building unit tests for our framework. As you noticed, we have no concrete classes – this is by design. So…how do we test interface and abstract classes? Why are we creating interfaces again?

The answer to question 2 is loose coupling and ability to test classes in isolation. This also promotes our core design principles and the supporting design patterns, which we covered in the “How to design and build better software for tomorrow?” series.

How do we test interface and abstract classes? The best approach is creating mock objects that implement the interfaces and inherit the base classes. The mock objects will mimic our concrete implementations, but with no real business logic. The following is the Framework Test project structure, which will contain our unit test and mock classes. 

The following is the EntityMock class, which inherits the EntityBase and defines the Generic type as int. This will represent the Id property type.

01
using System;
02
using Joemwalton.Framework.Domain;
03
 
04
namespace Joemwalton.Framework.Test.Mocks
05
{
06
    public class EntityMock 
07
        : EntityBase<int>
08
    {
09
        public EntityMock() 
10
        {
11
            this.Id = 1;
12
            Validate();
13
        }
14
 
15
        protected override void Validate()
16
        {
17
            this.FailedValidations.Clear();
18
            if (this.Id == 1)
19
                FailedValidations.Add("Testing");
20
        }
21
    }
22
}

The mock object contains an implementation for the constructor and Validate method, since the EntityBase handled the Id property. The following is the RepositoryMock class, which will focus on the relevant method implementation to support the framework.

01
using System;
02
using System.Collections.Generic;
03
using Joemwalton.Framework.Data.Repository;
04
using Joemwalton.Framework.Test.Mocks;
05
 
06
namespace Joemwalton.Framework.Test.Mocks
07
{
08
    public class RepositoryMock 
09
        : IRepository<EntityMock, int>
10
    {
11
        public void Save(EntityMock entity)
12
        {
13
            throw new NotImplementedException();
14
        }
15
 
16
        public void Remove(EntityMock entity)
17
        {
18
            throw new NotImplementedException();
19
        }
20
 
21
        public EntityMock FindById(int id)
22
        {
23
            return new EntityMock();
24
        }
25
 
26
        public List<EntityMock> FindAll()
27
        {
28
            return new List<EntityMock> { new EntityMock() };
29
        }
30
    }
31
}

The mock object implements the IRepository interface, where the contract defines the basic CRUD operations. The method implementation is not important, since we are not testing the ability of the Repository to retrieve or persist objects. The IRepository is a Generic interface, so the concrete entity type definition is required.

With the mock objects available, we can build our unit tests for the entity and Repository framework. In the following, the unit tests are based on the Microsoft Visual Studio Test libraries, although you can also build your tests with the open source NUnit framework. In either case, the goal is building the necessary unit tests for the framework.

01
using System;
02
using Microsoft.VisualStudio.TestTools.UnitTesting;
03
using Joemwalton.Framework.Data.Repository;
04
using Joemwalton.Framework.Test.Mocks; 
05
 
06
namespace Framework.Test
07
{
08
    [TestClass]
09
    public class EntityTest
10
    {
11
        public EntityTest() { }
12
 
13
        public TestContext TestContext { get; set; }
14
 
15
        [TestMethod]
16
        public void GetIdTest()
17
        {
18
            EntityMock mock = new EntityMock();
19
            int expected = 1;
20
            Assert.AreEqual(expected, mock.Id);
21
        }
22
 
23
        [TestMethod]
24
        public void SetIdTest()
25
        {
26
            EntityMock mock = new EntityMock();
27
            int expected = 2;
28
            mock.Id = expected;
29
            Assert.AreEqual(expected, mock.Id);
30
        }
31
 
32
        [TestMethod]
33
        public void GetFailedValidationsTest()
34
        {
35
            EntityMock mock = new EntityMock();
36
            Assert.AreEqual(1, mock.GetFailedValidations().Count);
37
            string expected = "Testing";
38
            Assert.AreEqual(expected, mock.GetFailedValidations()[0]);
39
        }
40
    }
41
}

In the above EntityTest class, we decorate the class with TestClass and test methods with TestMethod attributes. The test methods create an instance of the EntityMock and validate the results, although the EntityMock instantiation can also be accomplished during the test class initialization and shared for all test methods. The following is the RepositoryTest, which follows the same approach as the EntityTest.

01
using System;
02
using System.Text;
03
using System.Collections.Generic;
04
using System.Linq;
05
using Microsoft.VisualStudio.TestTools.UnitTesting;
06
using Joemwalton.Framework.Test.Mocks;
07
 
08
namespace Joemwalton.Framework.Test
09
{
10
    [TestClass]
11
    public class RepositoryTest
12
    {
13
        public RepositoryTest() { }
14
 
15
        public TestContext TestContext { get; set; }
16
 
17
        [TestMethod]
18
        [ExpectedException(typeof(NotImplementedException))]
19
        public void SaveTest()
20
        {
21
            RepositoryMock mock = new RepositoryMock();
22
            mock.Save(new EntityMock());
23
        }
24
 
25
        [TestMethod]
26
        [ExpectedException(typeof(NotImplementedException))]
27
        public void RemoveTest()
28
        {
29
            RepositoryMock mock = new RepositoryMock();
30
            mock.Remove(new EntityMock());
31
        }
32
 
33
        [TestMethod]
34
        public void FindByIdTest()
35
        {
36
            RepositoryMock mock = new RepositoryMock();
37
            EntityMock expected = new EntityMock();
38
            EntityMock actual = mock.FindById(1);
39
            Assert.AreEqual(expected.Id, actual.Id);
40
        }
41
 
42
        [TestMethod]
43
        public void FindAllTest()
44
        {
45
            RepositoryMock mock = new RepositoryMock();
46
            EntityMock expected = new EntityMock();
47
            List<EntityMock> actual = mock.FindAll();
48
            Assert.AreEqual(1, actual.Count);
49
            Assert.AreEqual(expected.Id, actual[0].Id);
50
        }
51
    }
52
}

The next step is run the tests. This is simple using Visual Studio, which includes several convenient options depending on your version. The Test menu or toolbar will provide an option to “Run All Tests in Solution”, which will run the tests and report the results. Alternatively, the Test View window will provide another interface to run tests.

In the Test View, you can highlight all tests and select “Run Selection” from the toolbar. This will execute the unit tests and display the information in the Test Results window, which appears below.

As you can see, the Test View window also provides several options to run and debug tests. Unfortunately, you will lose these handy features with an open source or non-Microsoft test tool.

In summary, we created mock objects for our domain model and Repository framework. Once we developed the mock objects, we created unit tests to ensure the relevant base implementation is working as expected. As we refactor the framework, the unit tests will ensure changes do not introduce bugs or break existing features. The introduction of a Continuous Integration (CI) process will further extend the test value with an event-driven build and test execution process. This can be accomplished using Microsoft Team Foundation Server (TFS), CruiseControl.NET, Team City or several other CI products.

What’s next? The next installment will focus on NHibernate including the SessionFactory, mapping and transaction management. This will segue into the IoC and Spring.NET support, which will provide many time saving NHibernate features.

Finally, I received several requests for a Java implementation. So…I am planning to build a Java equivalent enterprise framework solution. Thanks again for your comments and suggestions!!!!

Previous: Building Enterprise Frameworks – Data and Domain

Thinking Enterprise Architecture

Building Enterprise Frameworks – Data and Domain

0

In the previous blog entry “Thinking Enterprise Architecture”, I presented the background for a series focusing on Enterprise Architecture. Previously, we discussed the core design principles for software development. We also introduced several design patterns to satisfy the core principles. The concepts were applied to several technologies and demonstrated using Inversion of Control (IoC), Model-View-Controller (MVC) and Windows Communication Foundation (WCF). Since the core design principles and design patterns are not framework or language specific, the “Part VI: Brick Design – How to design and build better software for tomorrow?” article was a Java implementation of the Contact Manager application.

In this entry, I will provide the preliminary enterprise framework core components supporting the domain model and data tier. I will emphasize the word preliminary, because the framework will evolve and refactoring will be required to satisfy our objectives. I will loosely base the framework on the design built by the team introduced in the background entry, since they prefer not to share all design and implementations. The project will be based on my standard Contact Manager application. Basically, we are separating the common components and establishing a framework to build enterprise applications.

First, we create a new project as a class library for the common enterprise framework. The project contains the Data and Model root folders, which are collections of interface and abstract classes. These are not our concrete implementations, but the shared objects that our enterprise projects reference.

The Domain folder includes the IEntity interface and the abstract EntityBase class. All domain model concrete classes should implement IEntity. The interface is our contract, so this should drive the implementations within an interface-based system. The interface includes the Id property, which is the only domain object property that should be common for all concrete implementations.

1
using System;
2
 
3
namespace Joemwalton.Framework.Domain
4
{
5
    public interface IEntity<TId>
6
    {
7
        TId Id { get; set; }
8
    }
9
}

We elected to create a Generic interface, so we can define the types at run-time and not design-time. In this case, our Id property type is unknown. The implementation will define the type, so we are not forced to commit in the contract.

The EntityBase is an abstract class, which serves as a base class to define shared behavior for an implementation to inherit. This class is providing the implementation for the common entity Id property and validation logic. In this domain-driven design, we are encapsulating the business rules for validating the domain object. The Validate method is abstract, since only the concrete implementation would be aware of the validation logic required for the domain object. As we refactor the framework classes, the following will change to reflect our technical design.

01
using System;
02
using System.Collections.Generic;
03
 
04
namespace Joemwalton.Framework.Domain
05
{
06
    public abstract class EntityBase<TEntity,TId> 
07
        : IEntity<TId>
08
        where TEntity : IEntity<TId>
09
    {
10
        public  TId Id { get; set; }
11
 
12
        private List<string> _failedValidations = new List<string>();
13
        protected List<string> FailedValidations 
14
        {
15
            get { return _failedValidations; } 
16
        }
17
 
18
        public List<string> GetFailedValidations()
19
        {
20
            _failedValidations.Clear();
21
            Validate();
22
            return _failedValidations;
23
        }
24
 
25
        protected abstract void Validate();
26
    }
27
}

The next step is the skeleton design for the data tier, which includes the data access tier or repository. The repository is a memory-based domain collection, which is responsible for persisting and retrieving the domain objects. We will also build an interface and base class to support the concrete repository implementations. The IRepository interface is the contract, which includes methods for the standard Create-Read-Update-Delete (CRUD) operations. At this point, we would like all repository implementations to support the basic operations – Save, FindById, FindAll, Update and Delete. The concrete implemenations could include additional methods, which provide additional operations.

01
using System;
02
using System.Collections.Generic;
03
using Joemwalton.Framework.Domain;
04
 
05
namespace Joemwalton.Framework.Data.Repository
06
{
07
    public interface IRepository<TEntity,TId>
08
        where TEntity : IEntity<TId>
09
    {
10
        void Save(TEntity entity);
11
        void Remove(TEntity entity);
12
        TEntity FindById(TId id);
13
        List<TEntity> FindAll();
14
    }
15
}

Since our domain object type is unknown at design-time, we use generics to allow run-time assignments. The where clause is included as a contraint, so the run-time type must be IEntity. The TEntity represents the run-time domain object. The following RepositoryBase abstract class is a placeholder, so this will also be refactored as our design evolves.

01
using System;
02
using System.Collections.Generic;
03
using NHibernate;
04
using Joemwalton.Framework.Domain;
05
 
06
namespace Joemwalton.Framework.Data.Repository
07
{
08
    public abstract class BaseRepository<TEntity,TId> 
09
        : IRepository<TEntity,TId>
10
        where TEntity : IEntity<TId>
11
    {
12
        public void Remove(TEntity entity) { }
13
 
14
        public void Save(TEntity entity) { }
15
 
16
        public TEntity FindById(TId id)
17
        {
18
            return default(TEntity);
19
        }
20
 
21
        public List<TEntity> FindAll()
22
        {
23
            return new List<TEntity>() { default(TEntity) };
24
        }
25
    }
26
}

Next, the Data.NHibernate folder contains the NHibernateRepositoryBase abstract class. This class contains NHibernate implementation code including the SessionFactory. Since we also selected Spring.NET, the Spring framework Object-Relational Mapping (ORM) modules provides the plumbing for this support. The IoC container provides the features to simplify the configuration, NHibernate session and enterprise transaction management. This class will also require refactoring as the features and implementations are discovered, but the following is a start.

01
using System;
02
using NHibernate;
03
using Joemwalton.Framework.Data.Repository;
04
using Joemwalton.Framework.Domain;
05
 
06
namespace Joemwalton.Framework.Data.NHibernate
07
{
08
    public abstract class NHibernateRepositoryBase<TEntity,TId> 
09
        : BaseRepository<TEntity,TId>
10
        where TEntity : IEntity<TId>
11
    {
12
        private ISessionFactory sessionFactory;
13
 
14
        /// <summary>
15
        /// Session factory
16
        /// </summary>
17
        public ISessionFactory SessionFactory
18
        {
19
            protected get { return sessionFactory; }
20
            set { sessionFactory = value; }
21
        }
22
 
23
        /// <summary>
24
        /// Get current active session
25
        /// </summary>
26
        protected ISession CurrentSession
27
        {
28
            get { return sessionFactory.GetCurrentSession(); }
29
        }
30
    }
31
}

In summary, the above are the draft enterprise framework classes and refactoring will be required in the future installments of the series. In the next entry, we will build tests including the mock objects for our abstractions. Once the enterprise framework is established, we will create a Contact Manager application. So…stay tuned for the next article in this series!

Next: Building Enterprise Frameworks - Testing and Mock Objects

Previous: Thinking Enterprise Architecture

Thinking Enterprise Architecture

0

I recently met a friend and fellow software engineer to discuss his current project. We met earlier this year during my .NET Code Camp presentation. I appreciate his candid feedback and suggestions for future articles, since he is a very talented developer and fanatical baseball fan. Although I really enjoy baseball, I am more of a seasonal fan in October. He is also an advocate of the same software design principles and supporting design patterns outlined during the presentation, which I also featured in “How to design and build better software for tomorrow?” multi-part series.

The Project

The project entailed building three major back-office applications, so he assembled a development team for each application. The teams were instructed to follow the software design principles, which they all agreed were important. After several weeks, he was surprised that each team presented such different solutions. The data access layer choices were NHibernate, Linq2Sql and Entity Framework. Although all teams built web solutions, two teams selected Model-View-Controller (MVC) and the third team Model-View-Presenter (MVP). The teams also selected different Inversion of Control (IoC) frameworks, which included Spring.NET and Microsoft Unity. They also followed different validation and exception handling strategies. After he summarized the current status, he expressed his disappointment and frustration. He was obviously directing some of the blame at me. I apologized and sympathized with his frustration. After a brief baseball playoffs and politics conversation, I suggested we work together to rectify the current situation and develop a plan to get the projects back on track. He recognized the long-term impact would be detrimental to the organization, since they would be forced to maintain so many competing technologies, tools and implementations.

I am not surprised that three teams delivered three different solutions. The core principles provide guidance and promote well- designed software, which all three products exhibited. They encourage a design that meets the objectives of the organization and project, but not tightly coupled to any implementation. Change is expected. The ”How to design and build better software for tomorrow?” multi-part series demonstrated a variety of presentation, business and data access layer implementations. The same principles and design patterns were applied to console applications, WinForms and MVC. We developed concrete data access implementations using pure ADO.NET and LINQ. The core software design principles and patterns are also platform independent, so we built working .NET and Java applications.

After this explanation, he better understood the objective of the software design principles and patterns. We agreed all teams were successful and accomplished the objectives. What went wrong? How do we fix it?

Enterprise Architecture

The enterprise architecture is an organization-wide framework containing a collection of collaborating modules to support the organization’s needs, which is the foundation for a unified platform. This requires establishing the common infrastructure or framework promoting the same core software design principles and design patterns. I would also include the supporting processes.

The logical approach is building a common framework before launching the development of the domain-level modules, but we now have three working applications and no enterprise architecture. After reviewing the three applications, we noticed the teams built similar interfaces and abstract classes. They also share many common services and concrete implementations. These are all common framework candidates, but we were still faced with many decisions as the enterprise evolves. In the end, we decided to apply basic project management techniques and invite the three teams to participate in the sessions. We referred to the three applications as “prototypes” and discussed the technical merits of each including risk, cost and schedule assessments. The teams prepared demonstrations and discussed the technical design. Although the teams initially lobbied for their design, the project management techniques reduced the probability of a biased decision.

The following is a summary of the major decisions and foundation for building the framework.

  • Presentation/User Interface - MVC3 and Razor using view models
  • Business - service objects acting as the entry points coordinating the exchanges between presentation, other service objects and the data access layers
  • Domain – a rich domain-driven design (DDD) supporting enterprise validation
  • Data Access – persistence using NHibernate to SQL Server
  • IoC – Spring.NET

After a few weeks, the enterprise team started building the common framework based on the agreed technical design. Once the framework is complete, the team will refactor the three applications to integrate the common framework. Since the team followed the core software design principles and design patterns, this task will require much less work. The Dependency Injection (DI) pattern and IoC will simplify this process, so the team can focus on building the domain modules to satisfy the needs of the organization. The project schedule was pushed slightly to the right resulting in a delay, but all is not lost. The team is confident the common framework and wealth of reusable components will enable them to accelerate the schedule and deliver the products on time. They also agree the quality will be much improved. Maybe you did not notice, but I no longer refer to them as teams. The experience not only produced a unified enterprise framework, but they are now a unified team.

In the majority of my engagements, we always plan and build a common framework. If you do not have a dedicated team to maintain the common framework then appoint members from all project teams to participate. In both cases, the enterprise team should act as the change control board (CCB) to approve or deny change requests. It is critical to ensure changes do not break existing features or modules, so following the best testing practices is essential.

When the team extended an invitation to participate in this process, I could not decline the offer. They also agreed to allow me to blog about the experience and share with the community. So…I plan to chronicle the journey and decisions along the way including plenty of code examples. Please visit again soon…

Building Enterprise Frameworks – Data and Domain

Building Enterprise Frameworks – Testing and Mock Objects

Go to Top