José F. Romaniello

Las aventuras y desventuras de un codificador.

Just discovered a feature of ReSharper that help me a lot when writing unit tests.

Everytime I wrote “stub” + intro, resharper will introduce Mock.Of<SOMETHING>() and guess what? it will automagically fills the T argument. It is awesome, you can have a look here:

Unable to display content. Adobe Flash is required.

 

This is my Resharper live template:

2010-12-13_2137

| More

I’m currently working in a project with a legacy database. The database use a convention, where every table has his own identifier (one-column) and it must be generated by a sequence.

The name of the sequence follows a convention, first 26 characters of the Table name + the subfix “seq”. For instance, the sequence for the table Nationality is NATIONALITY_SEQ.

I take advantage of the convention as follows:

  • I’ve mapped everything as “native”.
  • I wrote a new id generator as follows:
public class SequenceByConvention : SequenceGenerator
{
    public override void Configure(IType type, IDictionary<string, string> parms, Dialect dialect)
    {
        parms["sequence"] = GetSequenceNameFromTableName(parms["target_table"]);
        base.Configure(type, parms, dialect);
    }
    private static string GetSequenceNameFromTableName(string tableName)
    {
        return tableName.Substring(0, Math.Min(26, tableName.Length)) + "_SEQ";
    }
}
  • And finally this is the dialect for this project:
public class MyDialect : Oracle10gDialect
{
    public override System.Type NativeIdentifierGeneratorClass
    {
        get { return typeof (SequenceByConvention); }
    }
}

| More

En mi entrada anterior explique el patrón Passive View". Ahora es el turno del patrón Supervising Controller.

Este patrón aprovecha la infraestructura de binding que posee winforms. A diferencia del Passive View, el View en este caso conoce un modelo al cual conectarse. Dado que el view puede interactuar con un modelo tanto su implementación como su interfaz es bastante mas simple en comparación con Passive View.

El Presenter en este caso se ocupa de la lógica mas complejas, mientras que el view se ocupa de la lógica simple, delegando esto último al mecanismo de databinding que usualmente se define de forma declarativa.

Sin más preámbulo, y siguiendo con nuestro ejemplo anterior esta es la interfaz del view:

public interface IEditarClienteView
{
    Cliente ClienteEnEdicion { get; set; }
    void CargarPaises(IEnumerable<Pais> paises);

    event EventHandler GuardarClick;
    event EventHandler CancelarClick;
    void Show();
    void Close();
}

Estos son los tests de nuestro presenter:

[TestFixture]
public class EditarClientePresenterTests
{
    public IRepositorioPaises CrearDobleDeRepositorioPaises()
    {
        var repositorioPaises = new Mock<IRepositorioPaises>();
        repositorioPaises.Setup(r => r.ObtenerOrdenadosPorNombre())
            .Returns(new[]
                         {
                             new Pais {CodigoIso = "AR", Nombre = "Argentina"},
                             new Pais {CodigoIso = "UY", Nombre = "Uruguay"}
                         });

        return repositorioPaises.Object;
    }

    private static IRepositorioClientes CrearDobleRepositorioClientes()
    {
        var repositorio = new Mock<IRepositorioClientes>();
        var cliente = new Cliente
        {
            Nombre = "Jose",
            Apellido = "Romaniello",
            Pais = new Pais { CodigoIso = "AR", Nombre = "Argentina" }
        };
        repositorio.Setup(r => r.Obtener(1)).Returns(cliente);
        return repositorio.Object;
    }

    [Test]
    public void AlIniciarCargarPaises()
    {
        var view = new Mock<IEditarClienteView>();

        var repositorioPaises = CrearDobleDeRepositorioPaises();
        var presenter = new EditarClientePresenter(
            view.Object,
            CrearDobleRepositorioClientes(),
            repositorioPaises);

        presenter.Iniciar(1);

        view.Verify(v => v.CargarPaises(repositorioPaises.ObtenerOrdenadosPorNombre()));
    }

    [Test]
    public void CuandoInicioCargoLosDatosDelCliente()
    {
        var view = new Mock<IEditarClienteView>();
        view.SetupAllProperties();

        var repositorioClientes = CrearDobleRepositorioClientes();

        var presenter = new EditarClientePresenter(
            view.Object,
            repositorioClientes,
            CrearDobleDeRepositorioPaises());

        presenter.Iniciar(1);
        view.Object.ClienteEnEdicion
            .Should().Be.SameInstanceAs(repositorioClientes.Obtener(1));
    }


    [Test]
    public void CuandoInicioMostrarForm()
    {
        var view = new Mock<IEditarClienteView>();
        view.SetupAllProperties();

        var presenter = new EditarClientePresenter(
            view.Object,
            CrearDobleRepositorioClientes(),
            CrearDobleDeRepositorioPaises());

        presenter.Iniciar(1);

        view.Verify(v => v.Show());
    }

    [Test]
    public void CuandoPresionoElBotonGuardarEntoncesGuardoConRepositorio()
    {
        var view = new Mock<IEditarClienteView>();
        view.SetupAllProperties();

        var repositorioClientes = CrearDobleRepositorioClientes();
        var cliente = repositorioClientes.Obtener(1);

        var presenter = new EditarClientePresenter(
            view.Object,
            repositorioClientes,
            CrearDobleDeRepositorioPaises());

        presenter.Iniciar(1);

        view.Raise(v => v.GuardarClick += null, EventArgs.Empty);

        Mock.Get(repositorioClientes).Verify(r => r.Actualizar(cliente));
    }


    [Test]
    public void CuandoCanceloCierroElForm()
    {
        var view = new Mock<IEditarClienteView>();
        view.SetupAllProperties();

        new EditarClientePresenter(
            view.Object,
            CrearDobleRepositorioClientes(),
            CrearDobleDeRepositorioPaises());

        view.Raise(v => v.CancelarClick += null, EventArgs.Empty);

        view.Verify(v => v.Close());
    }


}

Esta es la implementación del presenter:

public class EditarClientePresenter
{
    private readonly IEditarClienteView editarClienteView;
    private readonly IRepositorioClientes repositorioClientes;
    private readonly IRepositorioPaises repositorioPaises;

    public EditarClientePresenter(
        IEditarClienteView editarClienteView,  
        IRepositorioClientes repositorioClientes, 
        IRepositorioPaises repositorioPaises)
    {
        this.editarClienteView = editarClienteView;
        this.repositorioClientes = repositorioClientes;
        this.repositorioPaises = repositorioPaises;
        editarClienteView.GuardarClick += EditarClienteViewGuardarClick;
        editarClienteView.CancelarClick += EditarClienteViewCancelarClick;
    }

    void EditarClienteViewCancelarClick(object sender, EventArgs e)
    {
        editarClienteView.Close();
    }

    void EditarClienteViewGuardarClick(object sender, EventArgs e)
    {
        repositorioClientes.Actualizar(editarClienteView.ClienteEnEdicion);
        editarClienteView.Close();
    }

    public void Iniciar(int idCliente)
    {
        editarClienteView.CargarPaises(repositorioPaises.ObtenerOrdenadosPorNombre());
        editarClienteView.ClienteEnEdicion = repositorioClientes.Obtener(1);
        editarClienteView.Show();
    }
}

Ahora bien, esta es la implementación de nuestro view:

public partial class FormEditarCliente : Form, IEditarClienteView
{
    public FormEditarCliente()
    {
        InitializeComponent();
    }

    public Cliente ClienteEnEdicion
    {
        get { return (Cliente) clienteBindingSource.DataSource; }
        set { clienteBindingSource.DataSource = value; }
    }

    public void CargarPaises(IEnumerable<Pais> paises)
    {
        paisBindingSource.DataSource = paises;
    }

    public event EventHandler GuardarClick
    {
        add { GuardarButton.Click += value; }
        remove { GuardarButton.Click -= value; }
    }

    public event EventHandler CancelarClick
    {
        add { CancelarButton.Click += value; }
        remove { CancelarButton.Click -= value; }
    }
}

"clienteBindingSource" y "paisBindingSource" son controles en nuestro formulario creados al hacer databinding. Si alguien no conoce como hacer binding en winforms, aquí les dejo un mini-screencast:

Unable to display content. Adobe Flash is required.

Por último el código fuente puede ser descargado desde esta enlace.

| More

Este es el primer post de una serie que voy a escribir, explicando distintos patrones de Presentación para aplicaciones de escritorio, los cuales en general permiten la separación de responsabilidades. Dicha separación nos permitirá escribir tests de los diferentes artefactos.

En esta entrada voy a hablar puntualmente del patrón Passive View definido por Martin Fowler y voy a mostrar una implementación para un caso de uso sencillo. Hacia al final del artículo he dejado el link para descargar el código completo del ejemplo.

En este patrón el View expone una serie de métodos los cuales permiten al Presenter manejar cada uno de sus widgets (controles) y  sus respectivas propiedades. Una característica importante de este patrón es que el View no conoce ningún Modelo.

Imaginemos un caso de uso para editar los datos de un cliente, al iniciar la pantalla tenemos que mostrar los datos actuales del cliente, luego el usuario realizará modificaciones y guardará o cancelará.

Esta sería nuestra pantalla:

image

La interfaz del artefacto View se podría definir de la siguiente manera:

public interface IEditarClienteView
{
    string Nombre { get; set; }
    string Apellido { get; set; }
    string CodigoPais { get; set; }

    void CargarPaisParaSeleccion(string codigoIso, string nombre);

    event EventHandler GuardarClick;
    event EventHandler CancelarClick;
    
    void Close();
    void Show();
}

El Presenter sería algo así:

public class EditarClientePresenter
{
    private readonly IEditarClienteView editarClienteView;
    private readonly IRepositorioClientes repositorioClientes;
    private readonly IRepositorioPaises repositorioPaises;
    private int clienteEnEdicion;

    public EditarClientePresenter(IEditarClienteView editarClienteView, 
        IRepositorioClientes repositorioClientes, 
        IRepositorioPaises repositorioPaises)
    {
        this.editarClienteView = editarClienteView;
        this.repositorioClientes = repositorioClientes;
        this.repositorioPaises = repositorioPaises;
        editarClienteView.GuardarClick += EditarClienteViewGuardarClick;
        editarClienteView.CancelarClick += EditarClienteViewCancelarClick;
    }

    public void Iniciar(int idCliente)
    {
        clienteEnEdicion = idCliente;
        foreach (var pais in repositorioPaises.ObtenerOrdenadosPorNombre())
        {
            editarClienteView.CargarPaisParaSeleccion(pais.CodigoIso, pais.Nombre);
        }

        var cliente = repositorioClientes.Obtener(idCliente);
        
        editarClienteView.Nombre = cliente.Nombre;
        editarClienteView.Apellido = cliente.Apellido;
        editarClienteView.CodigoPais = cliente.Pais.CodigoIso;

        editarClienteView.Show();
    }

    private void EditarClienteViewCancelarClick(object sender, EventArgs e)
    {
        editarClienteView.Close();
    }

    private void EditarClienteViewGuardarClick(object sender, EventArgs e)
    {
        var cliente = repositorioClientes.Obtener(clienteEnEdicion);
        cliente.Nombre = editarClienteView.Nombre;
        cliente.Apellido= editarClienteView.Apellido;
        cliente.Pais = repositorioPaises.Obtener(editarClienteView.CodigoPais);
    }
}

Cabe mencionar que este presenter, así como la interfaz del view, nace a partir de una serie de tests que fui escribiendo al principio. Esta técnica se denomina comúnmente TDD, aunque sus derivados como BDD también son válidos. Esta es la serie de tests que definieron mi implementación:

using System;
using Moq;
using NUnit.Framework;
using PassiveView.Dominio;
using PassiveView.Repositorios;
using SharpTestsEx;

namespace PassiveView.Tests
{
    [TestFixture]
    public class EditarClientePresenterTests
    {
        public IRepositorioPaises CrearDobleDeRepositorioPaises()
        {
            var repositorioPaises = new Mock<IRepositorioPaises>();
            repositorioPaises.Setup(r => r.ObtenerOrdenadosPorNombre())
                .Returns(new[]
                             {
                                 new Pais {CodigoIso = "AR", Nombre = "Argentina"},
                                 new Pais {CodigoIso = "UY", Nombre = "Uruguay"}
                             });

            return repositorioPaises.Object;
        }

        private static IRepositorioClientes CrearDobleRepositorioClientes()
        {
            var repositorio = new Mock<IRepositorioClientes>();
            var cliente = new Cliente
                                    {
                                        Nombre = "Jose",
                                        Apellido = "Romaniello",
                                        Pais = new Pais {CodigoIso = "AR", Nombre = "Argentina"}
                                    };
            repositorio.Setup(r => r.Obtener(1)).Returns(cliente);
            return repositorio.Object;
        }

        [Test]
        public void AlIniciarCargarPaises()
        {
            var view = new Mock<IEditarClienteView>();

            var presenter = new EditarClientePresenter(
                view.Object,
                CrearDobleRepositorioClientes(),
                CrearDobleDeRepositorioPaises());

            presenter.Iniciar(1);

            view.Verify(v => v.CargarPaisParaSeleccion("AR", "Argentina"));
            view.Verify(v => v.CargarPaisParaSeleccion("UY", "Uruguay"));
        }

        [Test]
        public void CuandoInicioCargoLosDatosDelCliente()
        {
            var view = new Mock<IEditarClienteView>();
            view.SetupAllProperties();

            var presenter = new EditarClientePresenter(
                view.Object,
                CrearDobleRepositorioClientes(),
                CrearDobleDeRepositorioPaises());

            presenter.Iniciar(1);

            view.Object.Satisfy(v => v.Apellido == "Romaniello"
                                     && v.Nombre == "Jose"
                                     && v.CodigoPais == "AR");
        }

        [Test]
        public void CuandoInicioMostrarForm()
        {
            var view = new Mock<IEditarClienteView>();
            view.SetupAllProperties();

            var presenter = new EditarClientePresenter(
                view.Object,
                CrearDobleRepositorioClientes(),
                CrearDobleDeRepositorioPaises());

            presenter.Iniciar(1);

            view.Verify(v => v.Show());
        }

        [Test]
        public void CuandoGuardoCargarLosValoresDeLaPantalla()
        {
            var view = new Mock<IEditarClienteView>();
            view.SetupAllProperties();

            var repositorioClientes = CrearDobleRepositorioClientes();
            var cliente = repositorioClientes.Obtener(1);

            var presenter = new EditarClientePresenter(
                view.Object,
                repositorioClientes,
                CrearDobleDeRepositorioPaises());

            presenter.Iniciar(1);

            view.Object.Nombre = "Pedro";

            view.Raise(v => v.GuardarClick += null, EventArgs.Empty);

            cliente.Nombre.Should().Be.EqualTo("Pedro");

        }
        [Test]
        public void CuandoCanceloCierroElForm()
        {
            var view = new Mock<IEditarClienteView>();
            view.SetupAllProperties();

            
            var presenter = new EditarClientePresenter(
                view.Object,
                CrearDobleRepositorioClientes(),
                CrearDobleDeRepositorioPaises());

            view.Raise(v => v.CancelarClick += null, EventArgs.Empty);

            view.Verify(v => v.Close());
        }


    }
}

La implementación del view es algo que he hecho al final, y es la siguiente:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;

namespace PassiveView
{

    public partial class FormEditarCliente : Form, IEditarClienteView
    {
        private readonly BindingList<KeyValuePair<string, string>>  paises 
                = new BindingList<KeyValuePair<string, string>>();

        public FormEditarCliente()
        {
            InitializeComponent();

            cmbPaises.DataSource = paises;
            cmbPaises.DisplayMember = "Value";
            cmbPaises.ValueMember = "Key";
        }

        public string Nombre
        {
            get { return tNombre.Text; }
            set { tNombre.Text = value; }
        }

        public string Apellido
        {
            get { return tApellido.Text; }
            set { tApellido.Text = value; }
        }

        public string CodigoPais
        {
            get { return cmbPaises.SelectedValue.ToString(); }
            set { cmbPaises.SelectedValue = value; }
        }

        public void CargarPaisParaSeleccion(string codigoIso, string nombre)
        {
            paises.Add(new KeyValuePair<string, string>(codigoIso, nombre));
        }

        public event EventHandler GuardarClick
        {
            add { btAceptar.Click += value; }
            remove { btAceptar.Click -= value; }
        }

        public event EventHandler CancelarClick
        {
            add { btCancelar.Click += value; }
            remove { btCancelar.Click -= value; }
        }
    }
}

Este código esta escrito en el código behind del formulario.

Conclusiones

Este patrón tiene la ventaja de lograr una muy buena separación entre Model View y Presenter, nuestro código de view es relativamente sencillo y el view hace muy pocas cosas, por lo tanto podríamos decir que el patrón logra muy bien su objetivo.

Como desventaja podríamos decir, que en este caso de uso sencillo se puede observar que estamos desaprovechando las características de databinding que winforms nos ofrece, haciendo que la interfaz de nuestra View sea muy pesada (muchos métodos) y el mapeo entre propiedades y controles puede llegar a ser tedioso.

El código completo de este sencillo ejemplo puede ser descargado de aquí.

| More

Sometime ago I noticed that Visual Studio has a very nice feature that allows you to nest any file in any other. From the point of view of the Solution Explorer any file can be child of any other, that's the way that generated code work for WPF, Winforms, and even ASP.Net files.

But there is not an easy way to use this feature arbitrary on any type of file, or classes and classes, so why not build a VSPackage?

Well, this is the result of few hours of thinking.

Step 1 : Select the files to nest

First child, next the root is the preferred way.

1-SelectFiles

 

Step 2 : Nest in!

2-NestIn

 

Step 3 : Select the root or use the suggested

3-SelectTheRoot-OrUseTheDefault

 

done!

4-You-Are-Done

 

FAQ

Do I need this extension to see the files nested?
You don’t, this extension use a pretty standard feature of visual studio. The extension is only for doing the nest.

Where do I get this thing?
Download the bits right from the Visual Studio gallery!
The source code is here.

| More

I will show you in this post some internals of my HqlAddin project. The scenario is that I wanted to add highlighting for specific some specific things when editing hbm.xml files, and inside the query tag:

image

The first thing we need is a Format like this:

/// <summary>
/// Defines the string editor format for the hbm editor.
/// </summary>
[Export(typeof(EditorFormatDefinition))]
[ClassificationType(ClassificationTypeNames = Name)]
[Name(Name)] //The name of the Format
[UserVisible(true)] //this should be visible to the end user
[Order(Before = Priority.Default)] //set the priority to be after the default classifiers
internal sealed class StringFormat  : ClassificationFormatDefinition
{

    public const string Name = "StringFormat";

    /// <summary>
    /// Defines the visual format for the "StringClassifier" classification type
    /// </summary>
    public StringFormat()
    {
        DisplayName = Name;
        ForegroundColor = Colors.DarkRed;
    }
}

Pretty easy, this class define a format named StringFormat (which is internal to my extension), the format has a custom ForegroundColor. Nothing more, the other formats are exactly like this.

The next step is to write a IClassifierProvider :

[Export(typeof (IClassifierProvider))]
[ContentType("xml")]
internal sealed class StringClassifierProvider : IClassifierProvider
{
    [Import] private IClassificationTypeRegistryService classificationRegistry;

    #region IClassifierProvider Members

    public IClassifier GetClassifier(ITextBuffer textBuffer)
    {
        return textBuffer
            .Properties
            .GetOrCreateSingletonProperty(() => new StringClassifier(classificationRegistry));
    }

    #endregion
}

This classifier provider adds a Stringclassifier to the textbuffer for the content type “xml”. There are others content types that you can use like “code”, or the very basic “text”, on the other hand you can create your own Content Types for other file extensions.

Given the fact that all my classifier are based on regular expressions, I wrote a RegexBasedClassifier:

internal abstract class RegexBasedClassifier : IClassifier
{
    private readonly IClassificationTypeRegistryService classificationRegistry;

    protected RegexBasedClassifier(IClassificationTypeRegistryService classificationRegistry)
    {
        this.classificationRegistry = classificationRegistry;
    }

    public abstract string FormatterName { get; }

    public abstract IEnumerable<Regex> Regexs { get; }


    public IList<ClassificationSpan> GetClassificationSpans(SnapshotSpan span)
    {
        if (!span.IsInQueryTag()) return Enumerable.Empty<ClassificationSpan>().ToList();
        var startline = span.Start.GetContainingLine();
        var endline = (span.End - 1).GetContainingLine();
        var text = span.Snapshot.GetText(new SnapshotSpan(startline.Start, endline.End));

        return (from regex in Regexs
               from match in regex.Matches(text).OfType<Match>()
               select CreateSpan(span, match))
               .ToList();
    }

    private ClassificationSpan CreateSpan(SnapshotSpan span, Match match)
    {
        var snapshotSpan = new SnapshotSpan(span.Snapshot, 
                                            span.Start.Position + match.Index, 
                                            match.Length);
        return new ClassificationSpan(
            snapshotSpan, 
            classificationRegistry.GetClassificationType(FormatterName));
    }

    public event EventHandler<ClassificationChangedEventArgs> ClassificationChanged;
}

This base class check if the current line is inside a QueryTag (IsInQueryTag call), then it find the matches for all the regex defined in the derived class, and if it found a match then it create a ClassificationSpan with the FormatterName defined in the derived class.

So the implementations of the StringClassifier is:

internal class StringClassifier : RegexBasedClassifier
{
    public StringClassifier(IClassificationTypeRegistryService classificationRegistry)
        : base(classificationRegistry)
    {
    }

    public override string FormatterName
    {
        get { return StringFormat.Name; }
    }

    public override IEnumerable<Regex> Regexs
    {
        get { yield return new Regex(@"(\'[^\'\\]*(?:\\.[^\'\\]*)*\'*)"); }
    }
}

And the KeywordClassifier is this:

internal class KeywordClassifier : RegexBasedClassifier
{
    private readonly string[] keywords = new[]
            {
                "join", "from", "select",
                "new", "where", "and",
                "or", "band", "between",
                "not", "join", "left",
                "inner", "fetch", "in",
                "group", "by", "sum", "count",
                "coalesce", "null", "is", "like"
            };

    public KeywordClassifier(IClassificationTypeRegistryService classificationRegistry)
        : base(classificationRegistry)
    {
    }

    public override string FormatterName
    {
        get { return KeywordFormat.Name; }
    }

    public override IEnumerable<Regex> Regexs
    {
        get
        {
            return from keyword in keywords
                   select new Regex(string.Format(@"\b({0})\b", keyword));
        }
    }
}

You can look at the tests for these classes in the HqlAddin.Test project. Thats all, I hope you find it useful!

| More

He estado dedicando un buen tiempo a mi extensión para Visual Studio, llamada HqlAddin. Al trabajar una extensión que va a ser utilizada otro sistema (en este caso Visual Studio) me ha ocurrido que en ciertas ocasiones no se como se va a comportar dicho sistema. Si bien es cierto que dicho comportamiento debería estar documentado, ya sea de forma escrita o en UnitTests, en la vida real no siempre sucede eso. Es por ello que Reflector Pro me ha sido de gran utilidad a la hora de desarrollar nuevas funcionalidades, como también a la hora de resolver errores.

Utilizar Reflector Pro, es muy sencillo, luego de abrir el proyecto tenemos que ir al menú Reflector y clickear en “Choose Assemblies to Debug”:

2010-10-11_1952

Es probable que si es la primera vez que lo utilizamos nos solicite desactivar “Just My Code”.

Luego tenemos que seleccionar el ensamblado sobre el cual nos gustaría adentrarnos:

image

Y eso es todo…. una vez que le damos aceptar, Reflector descompilara el ensamblado que hayamos seleccionado y a partir de este momento podemos depurar dentro del ensamblado con F11.. paso a paso.

Algunas aclaraciones:

  • Si el ensamblado que seleccionamos, en su directorio tiene un archivo PDB, esto quiere decir que nosotros ya tenemos los símbolos de depuración. Aquí pueden suceder dos cosas:
    • Si nosotros tenemos el código fuente de ese ensamblado (en el estado en que estaba cuando se compilo), utilizar Reflector para este caso es innecesario. Pero igual se puede.
    • Si nosotros no tenemos el código fuente de ese ensamblado, lo mejor sería borrar el PDB del directorio en el que estaba, o simplemente dejar que reflector haga una copia a otro directorio y modifique temporalmente nuestras referencias. Esto luego se puede desactivar con un solo click.
  • Algunos ensamblados, de Visual Studio por ejemplo, están compilados de una manera que se llama “código optimizado”, si bien es posible seguir paso a paso la ejecución en este código, no es posible hacer cosas triviales como observar el valor de una variable.
  • Después de un tiempo de utilizar la herramienta, uno se da cuenta que hay algunas cosas que no están tan bien descompiladas, un caso típico son los bloques enumeradores:
public IEnumerable<int> EjemploEnumerador(string parametro)
{
    yield return 0;
    if (parametro == "a") yield return 1;
    yield return 32;
}

Hay que recordar que los bloques enumeradores son solo un truco del compilador, y por lo tanto, no esta tan fácil descompilarlo.

Estoy muy conforme con la herramienta y considero que es muy útil a la hora de trabajar con .Net.

Por último quería agradecer a RedGate por brindarme una licencia gratuita para utilizar en el desarrollo de mi proyecto OpenSource y a todas las empresas que siguen esta línea, tanto JetBrains, SharpCrafters, e inclusive el mismo Microsoft.

| More

A month ago I released HqlAddin Green Popotito. After talking with my friend Fabio Maulo, he convinced me to add support for hbm files. Well, that’s it, the new release add supports for hbm.xml files and I’ve absolutely dropped the support for “hql” files (sorry but this is not the standard way of writing named queries). So, “Green popotito” is the last version with support for hql files.

In this post I will talk about the features of the HqlAddin V 0.9 – Alpha 3.

Syntax highlighting

HqlAddin brings coloring to your queries:

image

as you can see here:

  • blue; for keywords
  • dark-red; for strings
  • blue-violet; for parameters

Even inside <![CDATA[ ]]> tags:

image

Error detection

Using the same parser inside NHibernate 3, HqlAddin can detects syntactical problems:

image

You can see the problem in three places;

  • The red wave underline
  • The tooltip text
  • and in the error list, you can see the exception of ANTLR, and navigate to the line with double click

This is another example of exception:

image

Intellisense

In order to get intellisense you need to do a little trick, explained in this link. If you don’t do this trick, the other two features explained above will work. I am not so happy with this code, specially with having to touch your code. I will enhance this on futures version, and maybe I will work to add another mechanism. But for now, I only have this. You can add this piece of code on any, any project, even in your data tests project.

A little explanation of the process; in order to get intellisense working, HqlAddin need access to your nhibernate configuration, so you have to export (with System.ComponentModel) an instance of NHibernate.Cfg.Configuration. It doesn’t care what version of NHibernate you are using. HqlAddin will search your configuration when:

  • You open a solution.
  • You build a solution.

The intellisense working:

image

image

image

This combo comes with french fries

Because you are given me an instance of NHibernate’s Configuration, I know when you fail. So, I call this feature “strongly typed hbm’s”. Because, configuring NHibernate actually means “to compile mappings”

This is the snapshot:

image

This is not a desired feature just a side effect :) and its out of the scope of the addin.

That’s all, as always said, I am way interested in your opinion.

| More

Today I have released a new version of the HqlAddin project, the version is 1.0.0.4550 – Alpha 2 (a.k.a. Green Popotito).

Green Popotito comes with a new amazing feature, intellisense for properties and entities. This is a great work that comes from Felice Pollano’s NhWorkbench, so kudos for him.

Before we continue, let me show you a short screencast of the tool:

 

How does this work?

You have to export (with MEF) your configuration in any assembly, hql addin will look the output path of the startup project and if it find an export will import the information to give you intellisense. Just write an export on any project, the build path can be anywhere. Follows the instructions here.

Any configuration of any version of NHibernate is ok. In order to update your intellisense (e.g. when you change your mappings) you will have to rebuild the solution ctrl + shift + b.

How to use the hql files?

You can read the full guide here.

Where do I get this?

You can download from the main website or simply from the Visual Studio Online Gallery of your Extension Manager. Read more here.

Provide feedback is mandatory

Please get involved with the project, provide some feedback, thoughts, issues or anything!

| More

I had an idea few days ago, about using an Enumerable Queryable as ServiceLocator, lets say a sequence of things that you can query.

I will explain this idea through simple tests. Suppose we have the following interface:

public interface IContainer
{
    IEnumerable<T> GetServices<T>();
    T GetService<T>();
}

1-It is a bad thing to ask to our ServiceLocator for all services so:

[Test]
public void WhenEnumeratingWithoutTypeThenThrowException()
{
    var container = new Mock<IContainer>();
    
    var sl = new QueryableLocator<object>(container.Object);
    
    sl.Executing(q => q.ToArray())
    .Throws<InvalidOperationException>()
    .And.ValueOf.Message
        .Should().Be.EqualTo("You must start with an OfType call.");
}

Prety easy to understand, if I try to enumerate for ALL services, just throw an exception

2-How to query all instances of a given type registered in the container.

[Test]
public void WhenEnumeratingWithOfTypeThenReturnAllInstancesOfTheGivenType()
{
    var container = new Mock<IContainer>();
    var serviceInstances = new []{"a", "b"};
    container.Setup(c => c.GetServices<string>())
             .Returns(serviceInstances);

    var sl = new QueryableLocator<object>(container.Object);
    sl.OfType<string>().ToArray()
            .Should().Have.SameValuesAs(serviceInstances);
}

I can query for all services implementing a given interface. Same stuff is on CommonServiceLocator.

3-How to get an instance of a given type

[Test]
public void WhenEnumeratingWithOfTypeAndCallingSingleThenResolveOnlyOneInstance()
{
    var container = new Mock<IContainer>();
    container.Setup(c => c.GetService<string>())
            .Returns("a");

    var sl = new QueryableLocator<object>(container.Object);
    sl.OfType<string>().Single()
        .Should().Be.Equals("a");
}

This is the most widely used scenario, doing sl.OfType().Single() is the same than commonServiceLocator.GetInstance()

4-Throw an exception when you try to do a Select, Count, Where, etc

[Test]
public void WhenExecutingAnUnrelatedLinqMethodThenThrowException()
{
    var container = new Mock<IContainer>();
    
    var query = new QueryableLocator<object>(container.Object);

    query.Executing(q => q.Count(s => true))
        .Throws<InvalidOperationException>()
        .And.ValueOf.Message
            .Should().Be.EqualTo("Count is not allowed over the service locator.");
}

Ok, this is all for now.

Advantages of QueryableServiceLocator over CommonServiceLocator

There are two big advantages:

  • You don’t need an extra assembly Microsoft.CommonServiceLocator. In fact IoC containers can provide their own implementation, so there is not need for an implementor assembly.
  • Easy to create Factories, you don’t need to write another interface/implementation for factories. Do you want a MessageHandlerFactory? var messageHandlerFactory = serviceLocator.OfType<IMessageHandler>().

TODOs

This is a rough idea, so far I don’t know how to handle the following two scenarios:

  • Retrieve a service by key, generally speaking a string key.
  • Create a factory of an open generic type, like “IRepository<>”

 

The implementation is right here. The class you might be interested on is this one.

Ideas?

| More

I started to work in an HQL addin for Visual Studio two weeks ago. As described in the project site:

This Visual Studio addin will provide the following features for the HQL file extension:
-syntax highlighting (done),
-syntax checking (done)
-intellisense (not yet)

Currently the addin support syntax highlighting and checking as you can see in the following screenshot:

2010-07-25_1011

One of the more interesting part of this, is that I have not implemented a parser or anything. I have only used the lexer and the parser inside NHibernate 3, so these features will be up to date always. In fact you can see the error “No viable alternative” that is common for most of the ANTLR parsers.

My idea is to support Intellisense as well, so I have reached Felice Pollano. He already has done a lot of work for other application named NHWorkBench and we are willing to cooperate for the intellisense part.

There is a step by step guid on how to use “hql” files with nhibernate here.

I have published an alpha release in the Visual Studio Online Gallery, so is very easy to install it:

2010-07-27_0845

If you are doing HQL have a look to my pluggin and let me know your comments!

| More

In a previous article I talked about an event publisher based on Reactive Extensions, and I wrote some examples of subscriptors based on IObservable.

I will talk about two different kind of subscriptors or observers in this post.

I am using this pattern in my presenters (user interface), so I will start this post with a simple example of use case.

The first interface is the “Albums Browser”:

myImage

And the second interface is the “Album Editor”:

myImage (1)

 

So, I have two concerns in this scenario:

  • I want to update the Browser when the user saves a change on an album.
  • I want to open the edit use case when the user press the button Edit. But I don’t want a hard reference to the Edit Album Presenter or window, in the browser.

So, I will declare two events:

public class AlbumUpdated
{
    public AlbumUpdated(int id)
    {    
        AlbumId = id;
    }

    //Poid of the album
    private object AlbumId{get; private set;}
}


public class AlbumEditRequest
{
    public AlbumUpdated(int id)
    {    
        AlbumId = id;
    }

    //Poid of the album
    private object AlbumId{get; private set;}
}

The command to raise the event is the same in both cases:

EventAggregator.Publish(new AlbumUpdated(id));

EventAggregator.Publish(new AlbumEditRequest(SelectedAlbum.Id));

But we need two kind of subscription mechanism.

Instance Subscription

The observers for AlbumUpdated are live object instances watching the event. So the browser for that matter look like this:

public class AlbumBrowserPresenter
{
    public AlbumBrowserPresenter(
        EventAggregator eventAggregator)
    {
        eventAggregator.GetEvent<AlbumUpdated>()
                    .Subscribe(ReloadGrid);
    }
    
    private void ReloadGrid()
    {
        //do the reload here.
    }   
}

And you can subscribe to this same event in other use cases, for instance when you have a selector for Albums.

Type Subscription

The observer of AlbumEditRequest is a type, this means that the handler of this event is not a live object. The event aggregator implementation “create” an instance of all types implementing the interface and then call an specific method. The edit presenter looks like this:

public class AlbumEditPresenter
  : IHandler<AlbumEditRequest>
{
    public void Handle(AlbumEditRequest @event)
    {
        InitWithId(@event.AlbumId);
    }

    //...
}

The easy way to handle this scenario in the event aggregator is something like this:

public void Publish<TEvent>(TEvent @event)
{
    object subject;

    if (subjects.TryGetValue(typeof(TEvent), out subject))
    {
        ((ISubject<TEvent>)subject)
            .OnNext(sampleEvent);
    }

    ServiceLocator.Current
                .GetAllInstances<IHandler<TEvent>>()
                .ForEach(h => h.Handle(@event));
}

This same code is used in many places and examples for Domain Events, but we use it here with other purpose.

| More

Luego de haber creado el script, como explique anteriormente en la Parte 1 de esta serie, lo que vamos a hacer es añadir nuestro proyecto a un servidor de integración continua. Para este ejemplo voy a utilizar TeamCity, aunque existen otros como CruiseControl, y el propio de TFS, Team Foundation Build.

TeamCity es por el momento mi preferido ya que su instalación es sencilla, su versión Profesional es gratuita y se integra muy bien con varias herramientas diferentes.

La instalación de TeamCity queda fuera del alcance de esta entrada, pero es muy sencilla. La única sugerencia sobre este punto es asignar una cuenta de correo, a la aplicación para que pueda comunicarnos cuando “metemos la pata”.

Crear un proyecto

2010-06-21_1726

Nada complicado, lo único que tenemos que hacer aquí es asignarle un nombre y una descripción a nuestro proyecto.

Configurar la conexión al servidor de control de versiones

2010-06-21_1729

Este paso es muy sencillo, aquí le diremos a TeamCity donde esta alojado el proyecto. Para este caso he seleccionado Subversion como control de versiones. Lo próximo que debo decirle es el url del proyecto, un nombre de usuario y contraseña. Luego hay muchas más opciones para configurar, pero los valores que vienen por defecto suelen ser los correctos.

Al final de esta página hay un botón para probar si los datos de conexión son válidos.

Crear una configuración para la generación

A continuación en la solapa “General” de la administración de nuestro proyecto debemos seleccionar la opción “Create Build Configuration”.

El proceso implica una serie de pasos, de los cuales los más importantes son el 2do y el 3ro:

2010-06-21_1736

En el segundo paso lo único que debemos hacer, es seleccionar el VCS root que creamos anteriormente.

A continuación, en el tercer paso, debemos configurar nuestro “Runner” acorde al script de generación que cree en mi post anterior, tal como sigue:

2010-06-21_1740

Build Runner; selccionamos MsBuild, ya que es la plataforma sobre la cual escribimos el script.

Build file path; nuestro xml de entrada, el nombre que le dimos en el post anterior fue default.build.

Luego lo más importante en esta página es la última configuración, que le dice a TeamCity que tiene que importar reportes de NUnit desde el path “$(OutputPath)\Reports\*.xml”.

Y esto es básicamente todo lo que hay que hacer para tener nuestro proyecto bajo integración continua. Los demás pasos tienen opciones por defecto que para proyectos simples son suficientes, y a medida que vayamos necesitando mas cosas como dependencias entre distintos proyectos dentro de nuestro proceso, podremos ir configurando.

| More

En esta serie de posts voy a explicar como empezar a trabajar con integración continua. Como el título lo dice, la razón por la que una persona o un equipo de desarrollo debería usar integración continua, trasciende el alcance de estos artículos. Deberías usarlo y ya!
El primer post va a estar dedicado a explicar como crear un “build script” para una solución de .Net.

Nota: Quiero agradecerle a Germán Schuager por enseñarme varias de las cosas que voy a explicar.

El script realizará los siguientes 4 pasos:

  1. Actualizar el número de versión en los archivos AssemblyInfo.cs, esto hará que nuestros resultados; (dlls, exes, etc) tengan un número de versión cuyo Build (recordar esquema Major.Minor.Build) coincida con la revisión de subversion.
  2. Compilar la solución, esto incluye todos sus proyectos.
  3. Ejecutar los tests de todos los proyectos de tests.
  4. Y finalmente copiar a una carpeta especifica el resultado de nuestro build.

Para ello utilizaremos la herramienta MsBuild.

Estructura de directorios

A continuación se muestra una estructura de directorios típica que se suele utilizar:

image

 

  1. Es un ejemplo de estructura de directorios que suelo utilizar.
  2. El contenido de la carpeta “Tools”. Se puede ver adentro dos carpetas
    • “msbuildtasks”: En esta carpeta colocaremos los binarios del proyecto MsBuild Community Tools. Este proyecto tiene Tasks adicionales para MsBuild.  Ya que el mismo, no conoce como interactuar con subversion, nunit u otras herramientas out-of-the-box. Un ejemplo de los archivos que van en este directorio se puede ver en ( 3 )
    • “nunit”: En esta carpeta colocaremos los binarios de nunit. Un ejemplo de los archivos que van en este directorio se puede ver en ( 4 ).

Common.targets

Al igual que todo el contenido de la carpeta “Tools”, se puede copiar prácticamente sin modificación alguna, de proyecto en proyecto. En el archivo common.targets resolveremos algunos asuntos, que ha continuación se pueden ver como comentarios de xml:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">

    <!-- Definicion  de Paths y algunas variables en general. -->
    <PropertyGroup>
        <MSBuildCommunityTasksPath>.</MSBuildCommunityTasksPath>
        <ToolsPath>Tools</ToolsPath>
        <NUnitPath>$(ToolsPath)\nunit</NUnitPath>
        <OutputPath>output</OutputPath>
        <ReportsPath>$(OutputPath)\Reports</ReportsPath>
        <ResultPath>$(OutputPath)\Build</ResultPath>
    </PropertyGroup>
    
    <!-- Importamos MsBuild Community Tasks. -->
    <Import Project="msbuildtasks\MSBuild.Community.Tasks.Targets" />
    
    <PropertyGroup>
        <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
        <FullVersion>$(BUILD_NUMBER)</FullVersion>
    </PropertyGroup>

    <!-- Tarea para actualizar mis AssemblyInfo.cs -->
    <Target Name="UpdateAssemblyInfos">
        <Message Text="Updating version numbers to $(FullVersion)..." />

        <CreateItem Include=".\**\AssemblyInfo.cs">
            <Output TaskParameter="Include" ItemName="AssemblyInfos"/>
        </CreateItem>
        
        <FileUpdate Condition="'$(FullVersion)' != ''"
            Files="@(AssemblyInfos)"
            Regex="\[\s*assembly\s*:\s*AssemblyVersion\s*\(\s*&quot;[\d\.\*]+&quot;\s*\)\s*\]"
            ReplacementText="[assembly: AssemblyVersion(&quot;$(FullVersion)&quot;)]" />
        <FileUpdate Condition="'$(FullVersion)' != ''"
            Files="@(AssemblyInfos)"
            Regex="\[\s*assembly\s*:\s*AssemblyFileVersion\s*\(\s*&quot;[\d\.\*]+&quot;\s*\)\s*\]"
            ReplacementText="[assembly: AssemblyFileVersion(&quot;$(FullVersion)&quot;)]" />
        <FileUpdate Condition="'$(FullVersion)' != ''"
            Files="@(AssemblyInfos)"
            Regex="\[\s*assembly\s*:\s*AssemblyInformationalVersion\s*\(\s*&quot;.*&quot;\s*\)\s*\]"
            ReplacementText="[assembly: AssemblyInformationalVersion(&quot;$(FullVersion)&quot;)]" />
    </Target>
    
    <!-- Tarea para compilar mi solucion en la configuracion seleccionada (debug o release)  -->
    <Target Name="DefaultBuild">
        <Message Text="Building $(SolutionFile)..." />
        <MSBuild Projects="$(SolutionFile)"
           Properties="Configuration=$(Configuration)" 
           ContinueOnError="false"   />
    </Target>
    
    <!-- Tarea para correr todos mis tests en el grupo de items definido para tal caso TestAssemblies -->
    <!-- Esta tarea genera reportes de nunit en format xml. En el directorio $ReportsPath. -->
    <Target Name="RunTests">
        <Message Text="Cleaning test reports folder..." />
        <RemoveDir Directories="$(ReportsPath)" />
        <MakeDir Directories="$(ReportsPath)" />
        <Exec Command="$(NUnitPath)\nunit-console-x86.exe @(TestAssemblies) /xml=$(ReportsPath)\%(TestAssemblies.Filename).xml" 
            IgnoreExitCode="true" />
    </Target>
    
    <!-- Tarea para copiar el resultado de mi proyecto al directorio $ResultPath -->
    <Target Name="CopyBuildResult">
        <Message Text="Cleaning build output folder..." />
        <RemoveDir Directories="$(ResultPath)" />
        <MakeDir Directories="$(ResultPath)" />
        <Message Text="xxx @(BuildResult)" />
        <Copy SourceFiles="@(BuildResult)" DestinationFolder="$(ResultPath)" />
    </Target>
    
</Project>

Default.build

Este archivo sí es propio de cada solución, y un ejemplo para este proyecto sería el siguiente:

<Project DefaultTargets="All" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">

    <!--Importar common.targets-->
    <Import Project="Tools\common.targets" />

    <!--declaro el path relativo al archivo de solución a compilar-->
    <PropertyGroup>
        <SolutionFile>MiProyecto.sln</SolutionFile>
    </PropertyGroup>
    
    <!--declaro los proyectos de tests que se deberían incluir-->
    <ItemGroup>
        <TestAssemblies Include="*Tests\bin\$(Configuration)\*Tests.dll" />
    </ItemGroup>
    
    <!--declaro la ubicación de los proyectos a incluir-->
    <ItemGroup>
        <BuildResult Include="MiProyecto.GUI\bin\$(Configuration)\*.*" />
    </ItemGroup>        
    
    <!--declaro el target All-->    
    <Target Name="All" DependsOnTargets="UpdateAssemblyInfos; DefaultBuild; RunTests; CopyBuildResult">
    </Target>
    
</Project>

$(Configuration) es una variable que dice si estamos en Debug o Release.
La especificación de proyectos de Tests  puede parecer un poco rara; podríamos haberla declarado de la siguiente manera

<ItemGroup>
    <TestAssemblies Include="MiProyecto.Domain.Tests\bin\$(Configuration)\MiProyecto.Domain.Tests.dll" />
    <TestAssemblies Include="MiProyecto.Data.Tests\bin\$(Configuration)\MiProyecto.Data.Tests.dll" />
</ItemGroup>

El problema que yo tuve con esto, era que cada vez que agregaba un proyecto de tests (cosa que suelo hacer a menudo) tenía que acordarme de modificar este script. Lo cual es poco práctico, por lo tanto aprovechando mi convención [Proyecto a Testear].Tests utilizaremos los wildcards (comodines) de MsBuild, de esta forma podremos agregar proyectos de tests a la solución sin necesidad de modiricar este archivo. Una cosa que deberemos tener especial cuidado, es cuando desde un proyecto de tests referenciamos otro proyecto de tests, cosa que en general trato de evitar.

Build.bat

El archivo build.bat lo utilizaremos para correr el script localmente, ya sea para probar el script, hacer deployment, etc. Este archivo tiene lo siguiente:

@echo off
call "%VS90COMNTOOLS%..\..\VC\vcvarsall.bat"
msbuild %~dp0default.build /t:All /nologo

La primer línea registra las variables de MsBuild así como el path donde se encuentra la herramienta, y la segunda ejecuta MsBuild. Si se usa Visual Studio 2008, se coloca %VS90COMNTOOLS%… mientras que si se usa 2010, se coloca %VS100COMNTOOLS%. Esto presupone que la maquina donde ejecutaremos el batch tiene instalado Visual Studio. De más esta decir que este no será el caso de nuestro servidor de integración continua.

Cabe destacar que MsBuild, no solamente viene con Visual Studio, sino que también viene con .Net Framework SDK.

Hay más…

Scripts: Lo que hice aquí con MsBuild, puede hacerse con muuuchas otras herramientas diferentes; entre ellas nant, rake, psake, etc. Cada una de ellas tiene sus ventajas y desventajas. Actualmente elijo MsBuild por que hace exactamente lo que quiero, dispone de muchos ejemplos, es sencillo crear nuestras propias tasks directamente en C#, y la mejor de todas… no hace falta instalar prácticamente nada.

Control de versiones: Si están usando un DCVS como Mercurial o GIT se hace un poco mas complicado el tema de asignar un número de versión a los ensamblados ya que estos sistemas no utilizan números para en sus checkins, pero he visto que hay tareas para tal propósito como por ejemplo MSBuild Mercurial Tasks.

Frameworks de Testing: Todos los frameworks de tests unitarios disponen de una herramienta para correr los tests en modo consola, así que debería ser trivial en caso que usen algo como xUnit o MbUnit. En el caso particular de MsTests es mas sencillo ya que esta soportado nativamente por msbuild.

En el próximo post voy a mostrar como dar de alta esto en nuestro servidor de integración continua.

| More

At uNhAddIns we have something called IEntityValidator and it is implemented for Castle Validations, NHibernate Validator, Validation Application Block and DataAnnotations. You can read Fabio Maulo’s post here.

Another interesting point of the DataAnnotations implementation is that I wrote a cache for the attributes and properties (there is not concept of engine in data annotations). You can see the whole pseudo-engine here.

Usage

Step 1, register your IEntityValidator in your container;

container.Register(Component.For<IEntityValidator>()
    .ImplementedBy<uNhAddIns.DataAnnotations.EntityValidator>()
    .Named("da-entity-validator"));

Step 2, inject your IEntityValidator any where, an example usage is in a base viewmodel (wpf), for implementing IDataErrorInfo

public class ViewModelBase
    : IDataErrorInfo
{
    string IDataErrorInfo.this[string columnName]
    {
        get
        {
            var errors = ServiceLocator.Current
                .GetInstance<IEntityValidator>("da-entity-validator")
                .Validate(this, columnName)
                .Select(iv => iv.Message)
                .ToArray();

            return string.Join(Environment.NewLine, errors);
        }
    }

    string IDataErrorInfo.Error
    {
        get
        {
            var errors = ServiceLocator.Current
                .GetInstance<IEntityValidator>("da-entity-validator")
                .Validate(this)
                .Select(iv => iv.Message)
                .ToArray();

            return string.Join(Environment.NewLine, errors);
        }
    }
}

I have registered the service with a key because, I've two services for IEntityValidator in my application. One for NHV used to validate entities, and another one for Data Annotations used to validate ViewModels.

| More

I will show in this post the why of linqspecs.

As an example; lets imagine the domain of Chinook where you have Artists, Albums and Tracks. I will start with this simple View Model;

public class AlbumBrowserViewModel
{
    public Artist SelectedArtist { get; set; }
    
    public DateTime? ReleasedDateFrom { get; set; }
    public DateTime? ReleasedDateTo { get; set; }

    public void Filter()
    {
        CurrentAlbums = 
    }

    public IEnumerable<Album> CurrentAlbums { get; private set; }
}

Pay attention to the line 10, because now I will explain four different approaches to query the data, abstracting the data access code and the separation of concerns for this case.


Data Access Object pattern (without Expressions)

We are going to start a Data Access Object with the following interface:

public interface IAlbumDao
{
    IEnumerable<Album> GetAlbumByArtist(Artist artist);
    IEnumerable<Album> GetAlbumReleasedBetweenDates(DateTime? fromDate, DateTime? toDate);
    IEnumerable<Album> GetAlbumByArtistReleasedBetweenDates(Artist artist, DateTime? fromDate, DateTime? toDate);
}

So, now we can start writing the first test as follows:

public void can_filter_by_artist()
{
    var dao = new Mock<IAlbumDao>();
    var rollingStones = new Artist();
    var someAlbum = new Album();
    var albumList = new List<Album>{someAlbum};

    dao.Setup(d => d.GetAlbumByArtist(rollingStones))
        .Returns(albumList);

    var browser = new AlbumBrowserViewModel(dao.Object);
    
    browser.SelectedArtist = rollingStones;
    browser.ReleasedDateFrom = null;
    browser.ReleasedDateTo = null;

    browser.Filter();

    browser.CurrentAlbums
        .Should().Have.SameValuesAs(albumList);
}

Injecting the dao in the view model, the implementation, so far is:

public void Filter()
{
    CurrentAlbums = albumDao.GetAlbumByArtist(SelectedArtist);
}
but in the end it will looks like:
public void Filter()
{
    if(SelectedArtist != null 
    && (ReleasedDateFrom == null || ReleasedDateTo == null))
    {
        CurrentAlbums = albumDao.GetAlbumByArtist(SelectedArtist);
        return;
    }
    if(SelectedArtist == null 
    && (ReleasedDateFrom != null || ReleasedDateTo != null))
    {
        CurrentAlbums = albumDao
                .GetAlbumReleasedBetweenDates(ReleasedDateFrom, ReleasedDateTo);
        return;
    }
    if(SelectedArtist != null 
    && (ReleasedDateFrom != null || ReleasedDateTo != null))
    {
        CurrentAlbums = albumDao
                .GetAlbumByArtistReleasedBetweenDates(ReleasedDateFrom, ReleasedDateTo);
        return;
    }
    CurrentAlbums = albumDao.GetAllAlbums(); //What?
}

As you can see our Dao needs three different methods for these queries, although you can call the GetAlbumByArtistReleasedBetweenDates method always (sometimes with null parameters) but still suffer from a severe symptom: this is not flexible. On the other hand it violates the SOLID principles, because often you will need to touch the IDao and Dao. So forget about the Open Closed principle.

Pros:
  • Easy to test.
  • You can use the full feature set of the ORM inside the method.
Cons:
  • Violates OCP.
  • You could end with DAOs with 30 query methods inside.

Data Access Object pattern (with Expressions)

Now, I will talk about this interface:

public interface IDao<T>
{
    IEnumerable<T> Retrieve(Expression<Func<T, bool>> predicate);
}

This Data Access Object is much better than the former, but yet still have an issue. This IDao is hard, and almost impossible to mock. The main problem is that you can’t easily compare expressions. So, in my personal experience i know two ways of mocking it:

  • Compile the expression and assert the return value for some inputs.
  • Use a DaoStub with an in-memory collection inside.

I am not going to talk about the former, because I’ve a post about the subject.

The second is easy to understand, reading this test:

public void can_filter_by_artist()
{
    var rollingStones = new Artist();
    var someGirls = new Album {Artist = rollingStones};
    var daoStub = new DaoStub<Album>()
                    .Insert(someGirls, new Album());
    
    var browser = new AlbumBrowserViewModel(daoStub);
    
    browser.SelectedArtist = rollingStones;
    browser.ReleasedDateFrom = null;
    browser.ReleasedDateTo = null;

    browser.Filter();

    browser.CurrentAlbums
        .Should().Contain(someGirls)
                 .And.Have.Count.EqualTo(1);
}

The DaoStub<T>:
public class DaoStub<T> : IDao<T>
{
    private readonly ICollection<T> repository = new List<T>();

    public IDao<T> Insert(params T[] someGirls)
    {
        someGirls.ToList().ForEach(repository.Add);
        return this;
    }

    public IEnumerable<T> Retrieve(Expression<Func<T, bool>> predicate)
    {
        return repository.Where(predicate.Compile());
    }
}

and the implementation to pass the first test:

public class AlbumBrowserViewModel
{
    private readonly IDao<Album> albumDao;

    public AlbumBrowserViewModel(IDao<Album> albumDao)
    {
        this.albumDao = albumDao;
    }

    public Artist SelectedArtist { get; set; }
    
    public DateTime? ReleasedDateFrom { get; set; }
    public DateTime? ReleasedDateTo { get; set; }

    public void Filter()
    {
        CurrentAlbums = albumDao
            .Retrieve(a => a.Artist == SelectedArtist);
    }

    public IEnumerable<Album> CurrentAlbums { get; private set; }
}

I like this approach, however the two methods has a conceptual issue, you are “testing” a query that will be never executed. The linq provider for objects may work different than the Entity framework linq provider, or the NHibernate provider. So, you need to test the queries against the database provider, and if is possible I will highly recommend to test against the real world database. To summarize

Pros:

  • Very flexible and powerful.
  • Doesn’t violate OCP.

Cons:

  • It is hard to test and mock.
  • If you don’t use carefully you can end with a lot of predicates all over the code.

Query object pattern (or my style of query object pattern)

Forget about the dao, and start thinking in the following interface:

public interface IAlbumBrowseQuery
{
    Artist SelectedArtist { get; set; }
    DateTime? ReleasedDateFrom { get; set; }
    DateTime? ReleasedDateTo { get; set; }

    IEnumerable<Album> Execute();
}

For this case, you will only have to map, the UI fields to the query properties, but believe me there are few cases like this. I have named the query like the use case on purpose, because for this case I don’t want anybody modifying this interface unless is required for the use case.

The test and implementation are very simple, and you can mock this interface as we have mocked the first IDao. So, you can test your ViewModel.

Pros:

  • If you give to the query an specific responsibility, this pattern does not violate the OCP principle.
  • You can use the full featured set of the ORM tool, for instance, you can write your queries even in hql but for this case I will highly recommend you the Criteria API. This is not so important when you are using EF because linq is the only way you can write queries.

Cons:

  • You have to write an interface and the implementation per each query.
  • This pattern is less flexible than using dao with expression, if you only use this pattern you can end with a lot of query objects.

LinqSpecs; my baby project

I will use a DAO interface like this:

public interface IDao<T>
{
    IEnumerable<T> Retrieve(Specification<T> specification);
}

And I’ve two specs like this:

public class ByArtistSpecification : Specification<Album>
{
    public ByArtistSpecification(Artist artist)
    {
        Artist = artist;
    }

    public Artist Artist { get; private set; }

    public override Expression<Func<Album, bool>> IsSatisfiedBy()
    {
        return a => a.Artist == Artist;
    }

    protected override object[] Parameters { get { return new[]{ Artist }; } }
}

You don’t need to mock this class in order to test your ViewModel. Lets add a test for this VM:

public void can_filter_by_artist()
{
    var rollingStones = new Artist();
    var someGirls = new Album ();
    var dao = new Mock<IDao<Album>>();


    dao.Setup(d => d.Retrieve(new ByArtistSpecification(rollingStones)))
        .Returns(new List<Album>{someGirls});

    var browser = new AlbumBrowserViewModel(dao.Object);
    
    browser.SelectedArtist = rollingStones;
    browser.ReleasedDateFrom = null;
    browser.ReleasedDateTo = null;

    browser.Filter();

    browser.CurrentAlbums
        .Should().Contain(someGirls);
}

It doesn't matter that you have two instances of ByArtistSpecification, they are equals if they share the same parameters (last method in the specification.

In fact I can write a setup like this:

dao.Setup(d => d.Retrieve(new ByArtistSpecification(rollingStones) &
                          new ByReleasedDateRangeSpecification(new DateTime(1984, 1, 1), 
                                                               new DateTime(1989, 1, 1))))
    .Returns(new List<Album>{someGirls});

 

Pros:

  • You write tests for what you should test
  • It is very flexible and powerful
  • You write less than with query objects
  • You can operate specifications &, | and ! are supported.
  • You can easily test the specifications targeting against the real provider.
  • Specifications are cheaper, you can even serialize them-

Cons:

  • Only works for linq, so you can access the full feature set of your ORM.
  • You need to write specifications (yet another artifact) :)

It goes without saying that the specification pattern is not a silver bullet, so you should choose the best pattern to meet your needs.

 

Thank you all! and I’m waiting for your comments.

| More

For those who do not follow me on Twitter.

I’ve created a new open source project named “LinqSpecs” in codeplex with the same concept described in this post.

The project is hosted here; http://linqspecs.codeplex.com/.

Have a look and try it!

| More

Usualmente uso este espacio solo para trasmitir cosas técnicas, pero esto me ha llenado tanto de orgullo que no pude evitar compartirlo con ustedes.

Mi abuelo, con “tan solo” 82 años de edad, terminó una carrera y recibió el título de “Técnico superior en administración de Cooperativas y Mutuales”.

Sin mas palabras les dejo un video de uno de los programas de televisión donde estuvo:



| More

This is the second part of my post about Event Aggregator. The idea is to show you an easy way to create and use an event aggregator in your application.

The interface of IEventAggregator in Prism looks as follows:

public interface IEventAggregator
{
    TEventType GetEvent<TEventType>() 
        where TEventType : EventBase;
}

Let’s go to see what is EventBase:

///<summary>
/// Defines a base class to publish and subscribe to events.
///</summary>
public abstract class EventBase
{
    private readonly List<IEventSubscription> _subscriptions = new List<IEventSubscription>();


    protected ICollection<IEventSubscription> Subscriptions
    {
        get { return _subscriptions; }
    }

    protected virtual SubscriptionToken InternalSubscribe(IEventSubscription eventSubscription)
    {
        eventSubscription.SubscriptionToken = new SubscriptionToken();
        lock (Subscriptions)
        {
            Subscriptions.Add(eventSubscription);
        }
        return eventSubscription.SubscriptionToken;
    }

    protected virtual void InternalPublish(params object[] arguments)
    {
        List<Action<object[]>> executionStrategies = PruneAndReturnStrategies();
        foreach (var executionStrategy in executionStrategies)
        {
            executionStrategy(arguments);
        }
    }

    public virtual void Unsubscribe(SubscriptionToken token)
    {
        lock (Subscriptions)
        {
            IEventSubscription subscription = Subscriptions.FirstOrDefault(evt => evt.SubscriptionToken == token);
            if (subscription != null)
            {
                Subscriptions.Remove(subscription);
            }
        }
    }

    public virtual bool Contains(SubscriptionToken token)
    {
        lock (Subscriptions)
        {
            IEventSubscription subscription = Subscriptions.FirstOrDefault(evt => evt.SubscriptionToken == token);
            return subscription != null;
        }
    }

    private List<Action<object[]>> PruneAndReturnStrategies()
    {
        List<Action<object[]>> returnList = new List<Action<object[]>>();

        lock (Subscriptions)
        {
            for (var i = Subscriptions.Count - 1; i >= 0; i--)
            {
                Action<object[]> listItem =
                    _subscriptions[i].GetExecutionStrategy();

                if (listItem == null)
                {
                    // Prune from main list. Log?
                    _subscriptions.RemoveAt(i);
                }
                else
                {
                    returnList.Add(listItem);
                }
            }
        }

        return returnList;
    }
}

Although its look fine, I think we can do less and achieve more with Reactive Extensions framework.

So, for this example my interface will look as follows:

public interface IEventPublisher
{
  void Publish<TEvent>(TEvent sampleEvent);
  IObservable<TEvent> GetEvent<TEvent>();
}

The first method is for publishing a TEvent, and the second method is used to get an IObservable of TEvent. I like this approach because I leverage too many things of the reactive framework. On the other hand, there is no restriction about TEvent, in fact, any class could be an event. Another interesting point, is that IObservable is part of the framework now.

Usage examples

Simple subscription

bool eventWasRaised = false;
var eventPublisher = new EventPublisher();

eventPublisher.GetEvent<SampleEvent>()
    .Subscribe(se => eventWasRaised = true);

eventPublisher.Publish(new SampleEvent());
eventWasRaised.Should().Be.True();

UnSubscribe

bool eventWasRaised = false;
var eventPublisher = new EventPublisher();

var subscription = eventPublisher.GetEvent<SampleEvent>()
    .Subscribe(se => eventWasRaised = true);

subscription.Dispose();
eventPublisher.Publish(new SampleEvent());
eventWasRaised.Should().Be.False();

Selective subscription

bool eventWasRaised = false;
var eventPublisher = new EventPublisher();

eventPublisher.GetEvent<SampleEvent>()
    .Where(se => se.Status == 1)
    .Subscribe(se => eventWasRaised = true);

eventPublisher.Publish(new SampleEvent{Status = 1});
eventWasRaised.Should().Be.True();

Subscribe to projection

bool eventWasRaised = false;
var eventPublisher = new EventPublisher();

eventPublisher.GetEvent<SampleEvent>()
    .Select(se => se.Status)
    .Subscribe(status => Console.WriteLine(status));

eventPublisher.Publish(new SampleEvent{Status = 1});

Observe on dispatcher

No matter what is the thread the event was published, execute the desired handler in the UI thread.

bool eventWasRaised = false;
var eventPublisher = new EventPublisher();

eventPublisher.GetEvent<SampleEvent>()
    .ObserveOnDispatcher()
    .Select(se => se.Status)
    .Subscribe(status => Console.WriteLine(status));

eventPublisher.Publish(new SampleEvent{Status = 1});

These are just examples of what you can do when you combine Reactive Extensions with Event Aggregator.

The implementation

This is the whole implementation:

public class EventPublisher : IEventPublisher
{
    private readonly ConcurrentDictionary<Type, object> subjects
        = new ConcurrentDictionary<Type, object>();

    public IObservable<TEvent> GetEvent<TEvent>()
    {
        var subject = 
            (ISubject<TEvent>) subjects.GetOrAdd(typeof (TEvent), 
                        t => new Subject<TEvent>());
        return subject.AsObservable();
    }

    public void Publish<TEvent>(TEvent sampleEvent)
    {
        object subject;
        if (subjects.TryGetValue(typeof(TEvent), out subject))
        {
            ((ISubject<TEvent>)subject)
                .OnNext(sampleEvent);
        }
    }
}

Finally

Prism is just wrong. Your events should be like POCOs, put the subscription elsewhere.

| More

The idea behind the Event Aggregation is to build loosely coupled components. In this post I’d like to introduce you a simple scenario for event aggregation.

Imagine that you are building the Microsoft Sql Server Management Studio Express, the “shell” of this program looks as follows:

This shell has a Create Connection panel and an Objects Explorer dialog. When the user press the Connect button, the connection must be added to the object explorer panel.

We will focus in this simple question:

Who is responsible to notify to the Object Explorer panel that a connection has been added?

I will not talk about MVVM, MVP, WPF and Winforms, this is pure theoretically.

Option A: direct notification

After processing the connect operation, the Connect use case, call a method in the object explorer:

objectExplorer.Add(theNewConnection);

The Connect use case needs to know too much about the Object Explorer use case, it needs a reference to the object explorer, ergo this is a bad design, because it violates almost any letter in S.O.L.I.D.

Option B: common events

The Connect use case has an event named ConnectionAdded and the Object explorer is subscribed to this event. We are moving the problem to the other side, the Connect use case is agnostic about the Object Explorer but the Object Explorer needs to know about the Connect use case, and this solution has the same problem that the former.

Option C: event publishing

Object explorer is subscribed to an event named ConnectionAdded which is defined as a class.

public class ObjectExplorer{

  public ObjectExplorer(IEventAggregator eventAggregator)
  {
     Connections = new List<Connection>();
     eventAggregator.Subscribe<ConnectionAdded>(AddConnection);
  }
  
  public IEnumerable<Connection> Connections{get; private set;}

  private void AddConnection(ConnectionAdded connectionAdded)
  {
     Connections.Add(connectionAdded.Connection);
  }
}

The Connect use case publish the event when its ready;

public class AddConnectionUseCase{

  private IEventAggregator eventAggregator;

  public AddConnectionUseCase(IEventAggregator eventAggregator)
  {
     this.eventAggregator = eventAggregator
  }
  
  private void Connect()
  {
     //do stuff
     eventAggregator.Publish<ConnectionAdded>(args);
  }
}

This is it. Any part of our system can publish this event, and any part of our system can be subscribed. This architecture is very extensible, flexible, easy to test and easy to maintain.

The concept is very close to Domain Events.

You can read more on Composite Application Guidance, also Ayende Rahien has an artifact in his Effectus application.

In my next post I’ll show you a concrete implementation of IEventAggregator.

| More