Friday, October 26, 2012

Razor @Sections, Javascript and the conundrum of EditorTemplates

With the exception of when using Modernizr I always try to adhere to the web performance rules of css at the top of the page and javascript at the bottom. The razor @RenderSection(string name, bool required) helper class and the @Section keyword certainly helps with that goal within view pages.

I recently came across this problem in a project for partial views. For instance if I create a DateTime.cshtml to represent an EditorTemplate for DateTime properties on View Models. I can't just inject the relevant scripts for the jQuery UI Date picker extension using the @section Scripts method like you can do within normal views.

So how can a developer adhere to best practices for stylesheets and script files? By using an extension method.

Let's start with adding a couple of extension methods, Resource and RenderResources as described below.

As you can see the Resource method takes a signature of Func<object, dynamic> template which simply can be @ so when template is executed the script tag is written into the page. The other parameter type is the type of resource being rendered "css" or "js", I've created a static helper class to remove the magic string.


In the layout:


In the partial :


I haven't tested with Asp .net bundle as yet but with little or no tweaking that should work as well.

Monday, July 9, 2012

Why isn't this test passing? Must be FakeItEasy's fault.

This is a cautionary tale. Before trawling through the different communities trying to work out why something isn't working and step back and look at your code with a bit of common sense.

I had this code in my WorkoutController.



        public ActionResult Edit(Guid id) {

            WorkoutViewModel workout _workoutService.FindById(id);

            if(Request.IsAjaxRequest()) {

                return PartialView("_WorkoutEditView",  workout);

            }

            return View("Edit",  workout);

        }



A part of the Action was being tested by this Unit Test.



        [Test]

        public void EditCallsFindById() {

            Guid newGuid Guid.NewGuid();

            _controller.Edit(newGuid);

            A.CallTo(_workoutService.FindById(Guid.Empty)).WithAnyArguments().MustHaveHappened(Repeated.Exactly.Once);        }



Every time I ran the test it failed and obviously continued to fail. It was driving me nuts. I start looking at the FakeItEasy wiki and started looking at StackOverflow.

I left the problem overnight and came back to it this morning. When I look at the test first thing it hit me. The signature of A.CallTo() that I was looking for was

public static IReturnValueArgumentValidationConfiguration CallTo(Expression<Func> callSpecification)

Hence when I changed my test to:

Code Snippet

        [Test]        public void EditCallsFindById() {
            
            Guid newGuid Guid.NewGuid();

            _controller.Edit(newGuid);

            A.CallTo(()=>_workoutService.FindById(Guid.Empty)).WithAnyArguments().MustHaveHappened(Repeated.Exactly.Once);
        }



That is I need to added the lambda expression.

The moral to this story is always cast a critical eye over your code before really getting into troubleshooting mode.

Friday, March 9, 2012

WebApi - An Example with Database Persistance

As discussed in my last post the new Web Api feature which is packaged with the MVC4 beta rollout allows for the use of Inversion Of Control (Dependency Injection) similar to that of MVC3.

In this post I am going to step through a "real life" Web Api project called "Healthy Muscle Web", which will allow consumers of the API to interact with a set of data relating to workouts. Whether the consumers be mobile applications (iPhone, Android), mashups or other web platforms (Ruby, php, AspNet MVC).

Let's start with a data model


Code Snippet

    public class Workout
    {
        public virtual Guid Id { get; set; }
        public virtual string DateTime { get; set; }
        public virtual string WorkoutName { get; set; }
    }



For the persistence I will be using NHibernate. Now onto the controller implementation. From my understanding in REST, there are 4 primary verbs that we are concerned with:


  1. POST: Create a new entity

  2. PUT: Update an existing entity

  3. GET: Retrieve a specified entity

  4. DELETE: Delete a specified entity





Code Snippet

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using NHibernate.Linq;
using WebApi.Data.Configuration;
using WebApi.Data.Models;

namespace WebApi.Controllers
{
    public class WorkoutController : ApiController
    {
        private readonly IUnitOfWork _unitOfWork;

        public WorkoutController(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

        // GET /api/workouts
        [HttpGet]
        public IEnumerable<Workout> Get()
        {
            return _unitOfWork.CurrentSession.Query<Workout>().AsEnumerable();
        }

        // GET /api/workout/5
        [HttpGet]
        public Workout Get(Guid id)
        {
            var workout = _unitOfWork.CurrentSession.Query<Workout>().SingleOrDefault(x => x.Id == id);

            //If entity expected does not exist return 404.
            if (workout == null)
                throw new HttpResponseException(HttpStatusCode.NotFound);

            return workout;
        }

        // POST /api/workouts
        [HttpPost]
        public HttpResponseMessage<Workout> Post(Workout workout)
        {
            var id = _unitOfWork.CurrentSession.Save(workout);
            _unitOfWork.Commit();

            var response = new HttpResponseMessage<Workout>
                (workout, HttpStatusCode.Created);
            response.Headers.Location = new Uri(Request.RequestUri,
                Url.Route(null, new { id }));

            return response;
        }

        // PUT /api/workouts
        [HttpPut]
        public Workout Put(Workout workout)
        {
            var existingWorkout = _unitOfWork.CurrentSession.Query<Workout>().SingleOrDefault(x => x.Id == workout.Id);

            //check to ensure update can occur
            if(existingWorkout==null)
                throw new HttpResponseException(HttpStatusCode.NotFound);

            //merge detached entity into session
            _unitOfWork.CurrentSession.Merge(workout);
            _unitOfWork.Commit();

            return workout;
        }

        // DELETE /api/workouts/5
        [HttpDelete]
        public HttpResponseMessage Delete(Guid id)
        {
            var existingWorkout = _unitOfWork.CurrentSession.Query<Workout>().SingleOrDefault(x => x.Id == id);

            //check to ensure delete can occur
            if(existingWorkout==null)
                return new HttpResponseMessage(HttpStatusCode.NoContent);

            _unitOfWork.CurrentSession.Delete(existingWorkout);

            _unitOfWork.Commit();

            return new HttpResponseMessage(HttpStatusCode.NoContent);
        }
    }
}



For some methods I am just returning an entity, in this case Workout, and in other instances I am returning a hopefully more informational HttpResponseMessage. For example, in the case of the Post of a new entity, I need to tell the REST Client the new location of the newly added product in the header. In other actions I am also throwing a HttpResponseException if the resource requested is not found as per the Get method.

The routing configuration in the Global.asax look like


Code Snippet

routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );



Looking at the WorkoutController there is a dependency on the interface IUnitOfWork


Code Snippet

    public interface IUnitOfWork : IDisposable
    {
        ISession CurrentSession { get; }
        void Commit();
        void Rollback();
    }



which has a concrete implementation of


Code Snippet

public class UnitOfWork : IUnitOfWork
    {
        private readonly ISessionFactory _sessionFactory;
        private readonly ITransaction _transaction;

        public UnitOfWork(ISessionFactory sessionFactory)
        {
            _sessionFactory = sessionFactory;
            CurrentSession = _sessionFactory.OpenSession();
            _transaction = CurrentSession.BeginTransaction();
        }

        public ISession CurrentSession { get; private set; }

        public void Dispose()
        {
            CurrentSession.Close();
            CurrentSession = null;
        }

        public void Commit()
        {
            if (_transaction.IsActive)
                _transaction.Commit();
        }

        public void Rollback()
        {
            _transaction.Rollback();
        }
    }



Nothing too out there at the moment (nor will there be)

I have two Structure Map Registries



Code Snippet

public class NHibernateRegistry : Registry
    {
        public NHibernateRegistry()
        {
            var cfg = new NHibernate.Cfg.Configuration()
                .SetProperty(Environment.ReleaseConnections, "on_close")
                .SetProperty(Environment.Dialect, typeof(MsSqlCe40Dialect).AssemblyQualifiedName)
                .SetProperty(Environment.ConnectionDriver, typeof(SqlServerCeDriver).AssemblyQualifiedName)
                .SetProperty(Environment.ConnectionStringName, "WebApi")
                .AddAssembly(typeof(Workout).Assembly);

            var sessionFactory = cfg.BuildSessionFactory();

            For<NHibernate.Cfg.Configuration>().Singleton().Use(cfg);

            For<ISessionFactory>().Singleton().Use(sessionFactory);

            
            For<ISession>().HybridHttpOrThreadLocalScoped()
                .Use(ctx => ctx.GetInstance<ISessionFactory>().OpenSession());

            For<IUnitOfWork>().HybridHttpOrThreadLocalScoped()
                .Use<UnitOfWork>();
        }
    }



and



Code Snippet

public class DomainRegistry : Registry
    {
        public DomainRegistry()
        {
            Scan(x =>
                     {
                         x.TheCallingAssembly();
                         x.WithDefaultConventions();
                     });
        }
    }



To bootstrap the IOC configuration I have a class



Code Snippet

public class DependencyRegistrar
    {
        protected static bool DependenciesRegistered;

        private static void RegisterDependencies()
        {
            ObjectFactory.Initialize(x => x.Scan(y =>
            {
                y.AssemblyContainingType<DomainRegistry>();
                y.AssemblyContainingType<NHibernateRegistry>();
                y.LookForRegistries();
            }));
        }

        private static readonly object Sync = new object();

        public void ConfigureOnStartup()
        {
            RegisterDependencies();
        }

        public static bool Registered(Type type)
        {
            EnsureDependenciesRegistered();
            return ObjectFactory.GetInstance(type) != null;
        }

        public static void EnsureDependenciesRegistered()
        {
            if (DependenciesRegistered) return;
            lock (Sync)
            {
                if (DependenciesRegistered) return;
                RegisterDependencies();
                DependenciesRegistered = true;
            }
        }
    }



The Global.asax is as follows



Code Snippet

protected void Application_Start()
        {
            new DependencyRegistrar().ConfigureOnStartup();

            var container = ObjectFactory.Container;

            GlobalConfiguration.Configuration.ServiceResolver.SetResolver(
                new StructureMapDependencyResolver(container));

            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);

            BundleTable.Bundles.RegisterTemplateBundles();
        }



EDIT: As Rob pointed out in the comments I'm not releasing the instances of IUnitOfWork so the disposing method is not being called, which could have an impact on the memory. Thanks Rob for the pick up. I've added the below code in the Global.asax which is called on the Appication_EndRequest event.


        protected void Application_EndRequest(object sender, EventArgs e) {
            ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
        }




The StructureMap configuration along with the Dependency Resolver (as discussed in my last post) allows for dependency injection.

You can see the full implementation at GitHub.com

Monday, February 27, 2012

Using StructureMap with Web API

To inject dependencies into your ASP.NET Web API controller we need to use the Web API dependency resolver. It is similar to the MVC 3 IDependencyResolver interface definition.

In the blog post I'll create a custom dependency resolver using StructureMap.

Firstly we need to create a class that inherits from IDependencyResolver which resides in the namespace System.Web.Http.Services.



Code Snippet

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http.Services;
using StructureMap;

namespace WebApi.Dependency
{
    public class StructureMapDependencyResolver:IDependencyResolver
    {
        public StructureMapDependencyResolver(IContainer container)
        {
            _container = container;
        }

        public object GetService(Type serviceType)
        {
            if (serviceType.IsAbstract || serviceType.IsInterface)
                return _container.TryGetInstance(serviceType);

            return _container.GetInstance(serviceType);
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            return _container.GetAllInstances<object>().Where(s => s.GetType() == serviceType);
        }

        private readonly IContainer _container;
    }
}



To register this with Web Api we use the Global.asax file with the Application_Start method insert the following code.


Code Snippet

var container = ObjectFactory.Container;
            GlobalConfiguration.Configuration.ServiceResolver.SetResolver(
                new StructureMapDependencyResolver(container));



so that the Application_Start method looks like


Code Snippet

        protected void Application_Start()
        {

            var container = ObjectFactory.Container;
            GlobalConfiguration.Configuration.ServiceResolver.SetResolver(
                new StructureMapDependencyResolver(container));

            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);

            BundleTable.Bundles.RegisterTemplateBundles();
        }



Now we can have controllers that use dependency injection.




Code Snippet

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using NHibernate.Linq;
using WebApi.Data.Configuration;
using WebApi.Data.Models;

namespace WebApi.Controllers
{
    public class WorkoutController : ApiController
    {
        private readonly IUnitOfWork _unitOfWork;

        public WorkoutController(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

        // GET /api/workouts
        public IEnumerable<Workout> Get()
        {
            return _unitOfWork.CurrentSession.Query<Workout>().AsEnumerable();
        }

        // GET /api/workout/5
        public Workout Get(Guid id)
        {
            return _unitOfWork.CurrentSession.Query<Workout>().FirstOrDefault(x => x.Id == id);
        }

        // POST /api/workouts
        public HttpResponseMessage<Workout> Post(Workout workout)
        {
            var id = _unitOfWork.CurrentSession.Save(workout);
            _unitOfWork.Commit();

            var response = new HttpResponseMessage<Workout>
                (workout, HttpStatusCode.Created);
            response.Headers.Location = new Uri(Request.RequestUri,
                Url.Route(null, new { id }));

            return response;
        }

        // PUT /api/workouts/5
        public Workout Put(Guid id, Workout workout)
        {
            var existingWorkout = _unitOfWork.CurrentSession.Query<Workout>().FirstOrDefault(x => x.Id == id);

            if(existingWorkout==null)
                throw new HttpResponseException(HttpStatusCode.NotFound);

            _unitOfWork.CurrentSession.Update(workout);
            _unitOfWork.Commit();
        }

        // DELETE /api/workouts/5
        public HttpResponseMessage Delete(Guid id)
        {
            var existingWorkout = _unitOfWork.CurrentSession.Query<Workout>().FirstOrDefault(x => x.Id == id);

            if(existingWorkout==null)
                return new HttpResponseMessage(HttpStatusCode.NoContent);

            _unitOfWork.CurrentSession.Delete(existingWorkout);

            _unitOfWork.Commit();

            return new HttpResponseMessage(HttpStatusCode.NoContent);
        }
    }
}



Happy Api creating.

Friday, February 24, 2012

Using knockout.mapping Plugin with Asp .Net MVC – Part 1a

In part 1 of this series I explored knockoutjs and completed a simple display view in the UI.

A few people have spoken to me about the implementation and commentated on what they perceived as a leakage into the Separation of Concerns regarding how bindings are managed via the data-bind attributes. While the comments certainly led to some interesting debates, I thought how can I remove some of those Concerns away from the UI.

Some research and I came across Neil Kerkin's blog post Exploring TodoMVC and knockout.js with unobtrusive bindings where he discusses an approach using knockout.js supports custom binding providers that allow us to refactor the code to achieve a bit more separation.

I won't go too much into what I have done because Neil explains it a lot better than I could. Therefore I'll just post the newer code base that will be used for part 2.

The javascript which looked like the following:

Code Snippet

(function (getworkouts, $, undefined) {    //create view model and initialise with default data.
    getworkouts.viewModel = function() {
        this.workouts = ko.mapping.fromJS(
                    [],
                    {
                        key: function (workout) { return ko.utils.unwrapObservable(workout.Id); }
                    });
                };    //use ajax call to populate the view model from the Action and also bootstraps knockout
    getworkouts.getDataFromSource = function () {
        $.ajax({
            type: 'POST',
            url: '/Home/GetWorkouts',
            dataType: 'json',
            success: function (data) {
                var model = new getworkouts.viewModel();
                model.workouts = ko.mapping.fromJS(data);
                ko.applyBindings(model);
            }
        });
    };
} (window.getworkouts = window.getworkouts || {}, jQuery));$(document).ready(function () {
    //bootstrap call
    getworkouts.getDataFromSource();
});


becomes

Code Snippet



/* File Created: February 5, 2;01;2 ;*/

(function (getworkouts, $, undefined) {

    window.setUpBindings.SetCustomBindings();

    //create view model and initialise with default data.

    getworkouts.viewModel = function () {

        this.workouts = ko.mapping.fromJS(

                    [],

                    {

                        key: function (workout) { return ko.utils.unwrapObservable(workout.Id); }

                    });

    };

    //use ajax call to populate the view model from the Action and also bootstraps knockout

    getworkouts.getDataFromSource = function () {

        $.ajax({

            type: 'POST',

            url: '/Home/GetWorkouts',

            dataType: 'json',

            success: function (data) {

                var model = new getworkouts.viewModel();

                model.workouts = ko.mapping.fromJS(data);

                getworkouts.bindings = {

                    workouts: { foreach: model.workouts },

                    workoutsDateTime: function () { return { text: this.DateTime }; },

                    workoutsWorkoutName: function () { return { text: this.WorkoutName }; }

                };

                //set ko's current bindingProvider equal to our new binding provider

                ko.bindingProvider.instance = new ko.customBindingProvider(getworkouts.bindings);

                ko.applyBindings(model);

            }

        });

    };

} (window.getworkouts = window.getworkouts || {}, jQuery));

$(document).ready(function () {

    //bootstrap

    getworkouts.getDataFromSource();

});

    



With an additional javascript snippet of

Code Snippet



/* File Created: February 16, 2012 */

(function (setupBindings, $, undefined) {

    setupBindings.SetCustomBindings = function() {

        ko.customBindingProvider = function(bindingObject) {

            this.bindingObject = bindingObject;

            //determine if an element has any bindings

            this.nodeHasBindings = function(node) {

                return node.getAttribute ? node.getAttribute("data-class") : false;

            };

            //return the bindings given a node and the bindingContext

            this.getBindings = function(node, bindingContext) {

                var result = { };

                var classes = node.getAttribute("data-class");

                if (classes) {

                    classes = classes.split(' ');

                    //evaluate each class, build a single object to return

                    for (var i = 0, j = classes.length; i < j; i++) {

                        var bindingAccessor = this.bindingObject[classes[i]];

                        if (bindingAccessor) {

                            var binding = typeof bindingAccessor == "function" ? bindingAccessor.call(bindingContext.$data) : bindingAccessor;

                            ko.utils.extend(result, binding);

                        }

                    }

                }

                return result;

            };

        };

    };

} (window.setUpBindings = window.setUpBindings || {}, jQuery));



The view then becomes

Code Snippet



<tableclass="gridtable">

    <thead>

        <tr>

            <th>

                Date Of Workout

            </th>

            <th>

                Name Of Workout

            </th>

        </tr>

    </thead>

    <tbody data-class="workouts">

        <tr>

            <td>

                    <span data-class="workoutsDateTime"></span>

            </td>

            <td>

                    <span data-class="workoutsWorkoutName"></span>

            </td>

        </tr>

    </tbody>

</table>



Once again the code is available at Github.

I've rushed over the implementation mainly because I don't want to any credit away from Neil Kerkin's solution to the Separation of Concerns problem.

See you at part 2.