Mariano Ravinale's Blog

Sharing Experiences

Archive for the ‘Asp.Net MVC’ Category

Asp.net MVC Simple CQRS part 3 – Command

leave a comment »

In this part we need to implement a mechanism that will change the state of our domain, this mechanism will be the CommandMessage.

this Command should delivery a message that will change the state of our domain, and our view should reflect that change.

after each commit or domain change, we should trigger a view update, for that reason I thaught that SignalR would be a good fit.

Example:

Command

public interface ICommand { }

public class DeleteAlbumCommand : ICommand
{
	public int Id { get; set; }
}

This command is an action that will be triggered by the user in order to delete an Album

CommandProcessor

public class CommandProcessor : IProcessCommand
{
	private readonly IWindsorContainer container;
	public CommandProcessor(IWindsorContainer container)
	{
		this.container = container;
	}	
	public void Execute(ICommand command)
	{
		dynamic handler = Assembly.GetExecutingAssembly()
					.GetTypes()									
					.Where(t =>typeof(IHandleCommand<>)
					.MakeGenericType(command.GetType()).IsAssignableFrom(t)
					 && !t.IsAbstract
					 && !t.IsInterface)	
					.Select(i => container.Resolve(i)).Single();

		handler.Handle((dynamic)command);
	}
}

Each command needs to be sent to the handler, for that we need a routing mechanism as well,
and that should be the resposability of the command processor.

Abstract CommandHandler:

public abstract class BaseCommandHandler<TCommand> : IHandleCommand<TCommand> where TCommand : ICommand
{
	public ISessionFactory SessionFactory { get; set; }
	public IConnectionManager ConnectionManager { get; set; }

	protected ISession Session
	{
		get { return SessionFactory.GetCurrentSession(); }
	}

	#region Implementation of IHandleCommand<TCommand>
		public abstract void Handle(TCommand command);
	#endregion
}

The BaseCommandHandler will provide the basic infrastructure to handle any business logic
these handlers will cause a change of the states of our domain, each command is particular action
for that will cause a change and after this change we need to alert or syncronize all clients.

CommandHandler


public class DeleteAlbumCommandHandler : BaseCommandHandler<DeleteAlbumCommand> 
{
	public override void Handle(DeleteAlbumCommand command)
	{
		var entity = Session.Get<Core.Album>(command.Id);
		Session.Delete(entity);

		//client side method invocation (update the clients!)
		ConnectionManager.GetClients<AlbumsHub>().Redraw();
	}
}

The mechanism and resposability for synchronize all domain changes will be asigned to SignalR, after each change
SignalR will trigger the redraw event of the datatable plugin, this event will update all the data that is
being displaying in that moment.

Handlers Installer: 

public class HandlersInstaller : IWindsorInstaller
{
	public void Install(IWindsorContainer container, IConfigurationStore store)
	{
      		var metadataProviderContributorsAssemblies = new[] { typeof (QueryProcessor).Assembly };
		container.Register(AllTypes.From(metadataProviderContributorsAssemblies
                                           .SelectMany(a => a.GetExportedTypes()))
                           .Where(t => t.Name.EndsWith("Handler") && t.IsAbstract == false)
                           .Configure(x => x.LifestyleSingleton())
        	);
      		
                container.Register(Component.For<IProcessQuery>()
                         .ImplementedBy<QueryProcessor>().LifeStyle.Singleton);
                container.Register(Component.For<IProcessCommand>()
                         .ImplementedBy<CommandProcessor>().LifeStyle.Singleton);

    	}
}

An example of the registration of our components using Windsor Castle Container.

MvcInstaller: 

 public class MvcInstaller : IWindsorInstaller
{
	public void Install(IWindsorContainer container, IConfigurationStore store)
	{
		container.Register(
			AllTypes.FromAssemblyContaining<HomeController>()
				.BasedOn<IController>()
				.WithService.Self()
				.Configure(cfg => cfg.LifestyleTransient()),
				
			Component.For<IControllerFactory>().ImplementedBy<WindsorControllerFactory>(),
			Component.For<IConnectionManager>().Instance(AspNetHost.DependencyResolver.Resolve<IConnectionManager>())
		
			);

		DependencyResolver.SetResolver(new WindsorDependencyResolver(container));
	}
}

Remeber that be need to register the SignalR components here you have an example of how
to register the IConectionManager.

Asp.Net MVC Controller’s example: 

public class AlbumsController : Controller
{
	public IProcessCommand CommandProcessor { get; set; }
	public ActionResult Index() { return View(); }

	[HttpPost]
	public void Delete(DeleteAlbumCommand command)
	{
		CommandProcessor.Execute(command);
	}
}

In our Controller we need to inject the command Processor, and execute
the delete command that contains the id of the album the we need to delete.

SignalR in Album.js: 

var Albums = (function ($) {
    var public = {};

    public.init = function (param) {
        initSignalR();
        initLayoutResources();
    };

    var initLayoutResources = function () {      
        $(".link").button();       

        $("#dialog").dialog({ autoOpen: false, modal: true });

        $(".edit-link").createForm({ baseUrl: "Albums/Edit/" });
        $(".details-link").createForm({ baseUrl: "Albums/Details/" });
        $(".insert-link").createForm({ baseUrl: "Albums/Insert/" });
        $(".delete-link").deleteAction({ baseUrl: "Albums/Delete/" });
    };

    var initSignalR = function () {
        //Create SignalR object to get communicate with server
        var hub = $.connection.AlbumsHub;

        hub.Redraw = function () {
            DataTable.reload();
        };
        // Start the connection
        $.connection.hub.start();
    };

  return public;

} (jQuery));

Remember that we need to update the state of the clients after each command action that
triggered a domain change, for that we should initialize the SignalR comunication with the server and
declare the redraw function that will call the jQuery Datatable reload method in order to update all the data.

Download or Fork the project on GitHub

May the code be with you!.

Mariano Ravinale

Creative Commons License

Written by @mravinale

octubre 14, 2012 at 9:05 pm

Publicado en Asp.Net MVC

Tagged with ,

Asp.net MVC Simple CQRS part 2 – Edit form using jquery dialog

with 2 comments

The goal:

Reuse all Asp.net MVC Form client/server validations functionality using jquery dialog.

This feature will be useful for this post series and for building general crud applications, as well.

Example:

First, let’s create our model:

public class AlbumModel
	{
		[Display(Name = "Id")]
		public int AlbumId { get; set; }

		[Required]
		public string Title { get; set; }

		[HiddenInput(DisplayValue = false)]
		[Display(Name = "Artists")]
		public int ArtistId { get; set; }

		public string ArtistName { get; set; }
		
		public IEnumerable<SelectListItem> Artists { get; set; }
	}

Now, we should create a partial view in order to render the Form

Edit.cshtml:

@model Chinook.Core.AlbumModel

@using (Html.BeginForm("Edit", "Albums",FormMethod.Post, new { id = "EditForm" }))
{
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Edit Album - @Model.AlbumId</legend>
         @Html.HiddenFor(model => model.AlbumId)
        <div class="editor-label">
            @Html.LabelFor(model => model.Title)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Title)
            @Html.ValidationMessageFor(model => model.Title)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ArtistId)
        </div>
        <div class="editor-field">
            @Html.DropDownListFor(model => model.ArtistId, Model.Artists, new { style = "width: 206px" })
            @Html.ValidationMessageFor(model => model.ArtistId)
        </div>
                <p>
			<input type="submit" value="Save" />
		</p>
    </fieldset>
}

<!--Lets add jquery validations for model Validations before submit-->
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8">
    $(document).ready(function () {
        $('#EditForm').ajaxForm({
            beforeSubmit: function () {
                return $('#EditForm').valid();
            },
            success: function () {
                $('#dialog').dialog("close");
            }
        });
    });
</script>

As you can see I’ve added jquery.validate.min.js and jquery.validate.unobtrusive.min.js this will executed when
the partial view is loaded after ajax call has been made.

A little peace of functionality must be writen first, two events:
before submit, verify all the fields are valid and
Success, when everything is ok close the dialog.

Album.js

$(function () {
    Albums.init();
});

//Module Pattern: http://tinyurl.com/crdgdzn
var Albums = function () {

  var initLayout = function () {
        $(".edit-link").button();
        $("#dialog").dialog({ autoOpen: false, modal: true });
    };

  var initEditForm = function () {
     $(".edit-link").live('click', function (event) {
        event.preventDefault();
         $.ajax({
             url: "Albums/Edit/1",
             success: function (data) {
                  $("#dialog").html(data);
                 $("#dialog").dialog('open');
             },
             error: function () { alert("Sorry,error"); }
          });
     });
   }
    // Reveal public pointers to
    // private functions and properties
    return {
        init: function () {
            initLayout();
            initEditForm();
        }
    };

} ();

Now in order to call the Form we need to add an ajax call, we should call to the server asking for the information and the html, and add this html to the div with the id “dialog”.

AlbumsController:

[HttpGet]
public ActionResult Edit(GetAlbumsByIdQuery query)
{
    return PartialView("Edit", QueryProcessor.Execute(query));
}

When someone calls to this method we will return the partial view with the information retrieved from the database.

Index.cshtml

<div id="demo">	
	<div>	   
	    <a class="edit-link" href="">Edit Album</a>
	</div>

	<table id="example" class="display" >
		<thead>
			<tr>
			   <th>Id</th>
			   <th>Title</th>
                           <th>Artist Name</th>
			</tr>
		</thead>
		<tbody></tbody>
	</table>
    
    <div id="dialog" title="Basic dialog"></div>
</div>

<script src="@Url.Content("~/Scripts/albums.js")" type="text/javascript"></script>

Finally the index page, here you can see the anchor that will be the trigger for the dialog call.
and the div that will be the container for the html form rendered.

in the next post, we’ll see how to render the data grid using http://datatables.net/ using ajax.

Download or Fork the project on GitHub

May the code be with you!.

Mariano Ravinale

Creative Commons License

Written by @mravinale

septiembre 23, 2012 at 9:04 pm

Publicado en Asp.Net MVC

Asp.net MVC Simple CQRS part 1 – Query

with 5 comments

Inspired by the Jeremy blog post crud its now cqrs or is it and
Gregory Young simple CQRS project: https://github.com/gregoryyoung/m-r

I’ve been working in a very simple insight for Asp.net MVC, in order to work comfortably in our business applications.

Quoting some words of Jeremy Likness: “CQRS provides what I think is a very valuable insight: that how you read and query data is probably very different from how you manage, update, and manipulate data. You don’t have to have a picture-perfect implementation of CQRS to take advantage of this concept”

image

The main Idea is to encapsulate our query and execute it using a processor, the processor wil be in charge to match each query to their handler in order to return the result from the data source.

Let’s take a look inside the code:

Query: Will define an unique query action with an expected result

public interface IQuery { }
public class GetAlbumsByIdQuery : IQuery
{
    public int Id { get; set; }
}

QueryProcessor: Will be in charge to match each query to their handler (using reflection and with a little help of dynamics) returning the handler’s result from the datasource.

public class QueryProcessor : IProcessQuery
{
	private readonly IWindsorContainer container;
	public QueryProcessor(IWindsorContainer container)
    	{
        	this.container = container;
    	}
 	public TResult Execute(IQuery query)
 	{
		 dynamic handler = Assembly.GetExecutingAssembly()
		 	.GetTypes()
			 .Where(t =>typeof(IHandleQuery)
			 .MakeGenericType(query.GetType(), typeof(TResult)).IsAssignableFrom(t)
			 	&& !t.IsAbstract
			 	&& !t.IsInterface)
			 .Select(i => container.Resolve(i)).Single();
		 return handler.Handle((dynamic)query);
 	}
}

Abstract QueryHandler: This abstract class will implement the base signature for each handler that we will create, in order to have NHibernate Infrastructure ready for our queries.

public abstract class BaseQueryHandler : IHandleQuery where TQuery : IQuery
{
	public ISessionFactory SessionFactory { get; set; }
	protected ISession Session
	{
        	get { return SessionFactory.GetCurrentSession(); }
	}
	#region IQueryHandler Members
	public abstract TResult Handle(TQuery query);
	#endregion
}

QueryHandler: Given the query and the returning signature we will execute the query and map the entity to our view Model using Automapper

public class GetAlbumsByIdQueryHandler : BaseQueryHandler
{
	public override AlbumModel Handle(GetAlbumsByIdQuery query)
 	{
 		var entity = Session.Get(query.Id);
		return Mapper.Map(entity);
 	}
}

Windsor Installer: 

public class HandlersInstaller : IWindsorInstaller
{
	public void Install(IWindsorContainer container, IConfigurationStore store)
	{
      		var metadataProviderContributorsAssemblies = new[] { typeof (QueryProcessor).Assembly };
		container.Register(AllTypes.From(metadataProviderContributorsAssemblies
                                           .SelectMany(a => a.GetExportedTypes()))
                           .Where(t => t.Name.EndsWith("Handler") && t.IsAbstract == false)
                           .Configure(x => x.LifestyleSingleton())
        	);
      		
                container.Register(Component.For<IProcessQuery>()
                         .ImplementedBy<QueryProcessor>().LifeStyle.Singleton);
                container.Register(Component.For<IProcessCommand>()
                         .ImplementedBy<CommandProcessor>().LifeStyle.Singleton);

    	}
}

Asp.Net MVC Controller’s example: 

public class AlbumsController : Controller
{
	public IProcessQuery QueryProcessor { get; set; }
	public ActionResult Index() { return View(); }

	[HttpGet]
	public ActionResult Details(GetAlbumsByIdQuery query)
	{
	      return PartialView("Details", QueryProcessor.Execute(query));
    	}
}

Now executing our query we’ll get the result in order to fill our view.

In case you are wondering about how to Handle NHibernate Session in Asp.net Mvc, I would recommend take a look to this post:

http://nhforge.org/blogs/nhibernate/archive/2011/03/03/effective-nhibernate-session-management-for-web-apps.aspx

And of course  read about mapping by code:

http://fabiomaulo.blogspot.com.ar/2011/04/nhibernate-32-mapping-by-code.html

Next post I’ll show the view, and command handling.

Download or Fork the project on GitHub

May the code be with you!.

Mariano Ravinale

Creative Commons License

Written by @mravinale

junio 20, 2012 at 5:48 pm

Publicado en Asp.Net MVC