José F. Romaniello

Las aventuras y desventuras de un codificador.

En este post voy a comentar un caso de uso del mundo real donde utilicé el patrón Visitor.

La historia comienza cuando en mi código me encontré con un método que estaba creciendo de tal forma que en poco tiempo tendría el siguiente aspecto (pseudo código):

public override void Procesar(FacturaViewModel entidad)
{
    //1-Crear Factura a partir de FacturaViewModel

    //2-Si la Factura implica mover stock
    //    Realizar Movimiento stock.

    //3-Si la Factura es de contado
    //    Realizar Operación Contable de Contado

    //4-Si la Factura es en Cuenta Corriente
    //    Realizar Operación Contable de CtaCte
    //    y generar comprobante XYZ

    //5-Si el monto total de la factura excede los 1000
    //    Aplicar consolidación de cliente

    //6-Si la Factura incluye "envases retornables"
    //    Generar comprobante de conformidad y
    //    actualizar info de envases XYZ

    base.Guardar(entidad);
}

Para simplificar he mencionado solo algunos escenarios o situaciones que se llevan a cabo en este proceso, según determinadas condiciones.

Esto era el ABC de mis servicios hasta hace algún tiempo, incluso es la forma que he utilizado ampliamente en aplicaciones VB6 (no estoy diciendo que ya no lo uso más). Este patrón esta muy bien explicado al estilo de Martin Fowler como Transaction Script.

Uno de los principales motivos por los cuales decidí este caso hacerlo con visitors, es que desde mi punto de vista esta suerte de Transaction Script tiene los siguientes problemas:

  • A mi criterio en algunos casos viola “Single Responsability Principle”; el principio dice que solo debería existir una razón para que una clase cambie. Depende en cierta forma de la granularidad que uno lo mire, pero para este escenario, encuentro la respuesta “Cambió el Script de Transacción” como inaceptable. Por lo tanto esta clase escrita de esta forma esta sujeta a cambios por múltiples razones:
    • Cambio la forma de tratar las facturas de contado.
    • Cambio la forma de mover stock.
    • etc.
  • Difícil de diseñar con TDD: esta es la razón principal que me hizo cambiar de idea en este escenario, realizar pruebas unitarias sobre un transaction script es prácticamente imposible. Lo que se debería hacer en realidad son pruebas con diferentes “escenarios” pero a mi criterio es mas una prueba de integración que unitaria. También quería destacar que configurar el contexto o escenario para la prueba involucra hacer mock de varios servicios.
  • Difícil de mantener y cambiar. Esto es el producto de los dos puntos anteriores.

Utilizando una especie de patrón Visitor

El patrón Visitor esta explicado en estos dos links (gracias a Fabio Maulo por los links y aclaraciones). La forma en que he aplicado el patrón es la siguiente, imaginese una interface así:

public interface IVisitor<T>
{
    bool Aplica(T entity);
    void Aplicar(T entity);
}

Esta interface tiene dos métodos. Aplica devuelve verdadero o falso dependiendo si el Visitor debe “visitar” dicha entidad del tipo T y el método Aplicar, que es el que finalmente ejecuta la acción sobre la entidad.

Mi servicio ahora tendría la siguiente forma

public class ServicioFacturacion 
{
    private readonly IVisitor<Factura>[] _visitors;
   
    public ServicioFactura(
        IVisitor<Factura>[] visitors, 
        ..) : base(..)
    {
        _visitors = visitors;
    }

    public override void Guardar(FacturaPedido entidad)
    {
        foreach (var visitor in _visitors)
        {
            if(visitor.Aplica(entidad))
            {
                visitor.Aplicar(entidad);
            }
        }
        base.Guardar(entidad);
    }
}

Como se puede ver el servicio ahora tiene una dependencia con un array de IVistor<Factura>. Probar esto es trivial:

var factura = new Factura();
var daoFactura = new Mock<IDao<Factura>>();

var visitor1 = new Mock<IVisitor<Factura>>();
visitor1.Setup(a => a.Aplica(factura)).Returns(true);

var visitor2 = new Mock<IVisitor<Factura>>();
visitor2.Setup(a => a.Aplica(factura)).Returns(false);


var modelo = new ServicioFacturacion(
        new[] {visitor1.Object, visitor2.Object},  
        new DaoFactoryMock().PushDao(daoFacturaPedido.Object));

modelo.Guardar(factura);


visitor1.VerifyAll();
visitor2.VerifyAll();
visitor2.Verify(a => a.Aplicar(factura), Times.Never());
visitor1.Verify(a => a.Aplicar(factura));
daoFactura.Verify(d => d.Save(factura));

Este test verifica:

  • Un visitor que aplica, debe aplicarse.
  • Un visitor que no aplica, no debe aplicarse.
  • El método Guardar del dao es llamado.

La idea en general es que uno ya esta usando inyección de dependencia y esto es muy fácil de configurar con cualquier container, por lo tanto nunca se construirá la instancia manualmente (excepto en el test je!). Aquí les dejo la referencia de como hacerlo con Castle Arrays, List and Dics.

Otra ventaja es que al estar dentro del Container, cualquier servicio puede ser inyectado en un Visitor.

Esto también nos da la posibilidad en el futuro de añadir visitors sin necesidad  de cambiar el servicio. Inclusive si los Visitors se crean en base a una interfaz pueden ser reutilizados en otros servicios similares.

Un ejemplo de un visitor es el siguiente:

public class VisitorMovimientoStock : IVisitor<Factura>
{
    private readonly IDaoReadOnly<Deposito> _daoDeposito;

    public VisitorMovimientoStock(IDaoFactory daoFactory)
    {
        _daoDeposito = daoFactory.GetDaoReadOnlyOf<Deposito>();
    }

    public bool Aplica(Factura entity)
    {
        return entity.Tipo.MueveStock;
    }

    public void Aplicar(Factura entidad)
    {
        var destino = _daoDeposito
                .First(d => d.Nombre == DepositosConocidos.EGRESO_VENTAS);

        var movimientosDeStock = entidad.Lineas
            .Select(l => l.ToMovimientoStock(entidad.PuntoVenta.DepositoVentas, destino))
            .ToList();

        entidad.AgregarMovimientosStock(movimientosDeStock);
    }
}

Hacer un test solamente de este aspecto es bastante fácil y voy a omitirlo.

Quería también pedir disculpas, por los nombres, sé que no son muy agradables. No me agrada mezclar ingles y castellano en los nombres de las clases, pero salió así!

Y por último comentar que este ejemplo es también parte del MundoReal.

| More

I will show in this article an approach to make an asynchronous call to the model, to prevent the user interface to freeze. If you read about WPF, you will see there is a lot of information and claims “don’t freeze the ui thread”, “build UI more responsiveness” and so on.

What you should know

NHibernate Sessions are not thread safe, so don’t use a single session in multiples threads. Conversation-per-Business-Transaction use the same session for a conversation. The end of the conversation flush the changes and close the session, the abort of the conversation discard changes and close the session.

You can’t update UI controls from a non-ui thread. Some people read this like “don’t set a ViewModel property from a non UI thread”. But this is not true, because it depends where do you raise the property changed notification thank to my friend German Schuager for reminding me this post from Rob Eisenberg. However, I’m not using this trick for now.

Asynchronous code is HARD to unit test. I will like to separate the asynchronous code in few units more testable and test “in-sync”.

The problem

The load of the artist list is very slow and this causes the user interface to freeze. This is very irritating for the end user.

I will break the async problem in the following three steps:

  1. Preview: Before start the operation we want to let the user know that the operation is in-process with some message in the user interface or maybe an hourglass.
  2. Process: The heavy operation.
  3. Completed: The operation has ended and we want to show the result to the UI.

Show me the code

This my generic implementation of ICommand for make async calls.

public class AsyncCommandWithResult<TParameter, TResult> 
        : IAsyncCommandWithResult<TParameter, TResult>
{
    private readonly Func<TParameter, bool> _canAction;
    private readonly Func<TParameter, TResult> _action;

    public AsyncCommandWithResult(Func<TParameter, TResult> action)
    {
        _action = action;
    }

    public AsyncCommandWithResult(
            Func<TParameter, TResult> action, 
            Func<TParameter, bool> canAction)
    {
        _action = action;
        _canAction = canAction;
    }


    public Action<TParameter, TResult> Completed { get; set; }
    public Action<TParameter> Preview { get; set; }
    public bool BlockInteraction { get; set; }

    public void Execute(object parameter)
    {
        //Execute Preview
        Preview((TParameter)parameter);

        //This is the async actions to take... 
        worker.DoWork += (sender, args) =>
            {
                args.Result = _action((TParameter)parameter);
                
            };

        //When the work is complete, execute the postaction.
        worker.RunWorkerCompleted += (sender, args) =>{
            Completed((TParameter) parameter, (TResult) args.Result);
            CommandManager.InvalidateRequerySuggested();
        };

        //Run the async work.
        worker.RunWorkerAsync();
    }

    [DebuggerStepThrough]
    public bool CanExecute(object parameter)
    {
        if(BlockInteraction  && worker.IsBusy )
            return false;

        return _canAction == null ? true : 
                _canAction((TParameter)parameter);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public TResult ExecuteSync(TParameter obj)
    {
        return _action(obj);
    }

    private readonly BackgroundWorker worker 
            = new BackgroundWorker();
}

Testing the ViewModel

Here you can see the test of the three steps. None of these test involves asynchronous calls.

[Test]
public void preview_of_load_list_should_show_status_info()
{
    var browseArtistVm = new BrowseArtistViewModel(
                new Mock<IBrowseArtistModel>().Object,
                new Mock<IViewFactory>().Object);
    
    browseArtistVm.LoadListCommand.Preview(null);
    browseArtistVm.Status.Should().Be.EqualTo("Loading artists...");
}

[Test(Description = "Check if the process call the model")]
public void load_list_command_should_load_artists_coll()
{
    var artistModel = new Mock<IBrowseArtistModel>();

    var artists = new List<Artist> {new Artist {Name = "Jose"}};

    artistModel.Setup(am => am.GetAllArtists()).Returns(artists);

    var browseArtistVm = new BrowseArtistViewModel(
                            artistModel.Object, 
                            new Mock<IViewFactory>().Object);

    browseArtistVm.LoadListCommand.ExecuteSync(null);

    artistModel.VerifyAll();
}

[Test]
public void completed_of_load_l_should_load_the_list_and_change_status()
{
    var browseArtistVm = new BrowseArtistViewModel(
                new Mock<IBrowseArtistModel>().Object,
                new Mock<IViewFactory>().Object);

    var artists = new List<Artist>();

    browseArtistVm.LoadListCommand.Completed(null, artists);

    browseArtistVm.Artists.Should().Be.SameInstanceAs(artists);
    browseArtistVm.Status.Should().Be.EqualTo("Finished");
}

Implementing the ViewModel

The LoadListCommand of the ViewModel is:

public virtual IAsyncCommandWithResult<object, IList<Artist>> LoadListCommand
{
    get
    {
        if (_loadListCommand == null)
        {
            _loadListCommand = 
                new AsyncCommandWithResult<object, IList<Artist>>
                        (o => _browseArtistModel.GetAllArtists())
                        {
                            BlockInteraction = true,
                            Preview = o => Status = "Loading artists...",
                            Completed = (o, artists) =>
                                {
                                    Artists = artists;
                                    Status = "Finished";
                                }
                        };
        }
        return _loadListCommand;
    }
}

Final conclusion

You must to remember that an NHibernate Session should be used in only one thread. This model for Browsing Artists has only one method with EndMode = End. This means session-per-call, so each time I click the LoadCommand the model start a new conversation and session. If you have a ViewModel with multiples operations within the same Conversation better you use something else, or use AsyncCommand everywhere within the VM.

There are a lot of alternatives to this approach, here are some;

Use this only when you need it. You don’t have to do this everywhere. Some operations are very fast and inexpensive.

Divide and conquer; I really like this way of testing. Don’t bring asynchronous things to your unit tests.

| More

String extensions

public static class StringExtensions
{
    public static string F(this string text, params object[] args)
    {
        return string.Format(text, args);
    }
}

This extension method is very clear and doesn't need explanation, usage:

"Hello, my name is {0}".F("Jose")

Int extensions

public static class IntExtensions
{
    public static IEnumerable<int> To(this int start, int end)
    {
        return Enumerable.Range(start, end);
    }
}

1.To(10) will returns an IEnumerable with elements from 1 to 10

Cast extension

public static class CastsExtensions
{
    public static T To<T>(this object o)
    {
        return (T)o;
    }

    public static T As<T>(this object o) where T : class
    {
        return o as T;
    }
}

This is self descriptive too. It allows you to cast and access a property with a more cleaner syntax: someObject.To<IDataErrorInfo>().Errors

Datetime extensions

public static class DateTimeExtensions
{
    public static DateTime FromNow(this TimeSpan self)
    {
        return DateTime.Now.Add(self);
    }
    public static DateTime From(this TimeSpan self, DateTime dateTime)
    {
        return dateTime.Add(self);
    }
    public static TimeSpan Days(this int days)
    {
        return TimeSpan.FromDays(days);
    }
}

I really like this extension method:

10.Days().FromNow()
    .Should().Be.EqualTo(DateTime.Today.AddDays(10));

10.Days().From(new DateTime(2009, 10, 10))
    .Should().Be.EqualTo(new DateTime(2009, 10, 20));

Enumerable extensions

public static class EnumerableExtensionsMethods
{
    public static void ForEach<T>(
            this IEnumerable<T> enumerable, 
            Action<T> action)
    {
        foreach (T item in enumerable)
        {
            action(item);
        }
    }
}

But, I already explained this in this post.

| More

As I said before, for the Chinook Media Manager I’m not using neither Caliburn nor Prism.
But, whenever I found a limitation on the current tools, I start looking a solution elsewhere. This is how I meet Caliburn.Testability, a great tool.

The problem

We don’t know what would be the ViewModel for the View at design time. This is the reason why we don’t have intelliscence in XAML, and in general our databinding are not strongly typed in XAML. So, we can write “naem” instead of “Name”.

The solution

Caliburn has a great tool named “Caliburn Testability”, you can read the full post here. As Rob Eisenberg said, I take this one step farther to build an automatic test.

This is the code:

public class DataBindingValidator
{
        private static BindingValidator ValidatorFor(
                Type guiElement, Type presenterType)
        {
            var boundType = new BoundType(presenterType);
            var instance = (DependencyObject)Activator.CreateInstance(guiElement);
            IElement element = Bound.DependencyObject(instance, boundType);
            return new BindingValidator(element);
        }

    /// <summary>
    /// Validate the bindings of a keyvalue pair 
    /// where the key is the View type and the 
    /// value is the ViewModel type.
    /// </summary>
    public IEnumerable<ValidationResult> 
            Validate(IDictionary<Type,Type> viewViewModelDictionary)
    {
        foreach (var viewViewModel in viewViewModelDictionary)
        {
            BindingValidator validator 
                = ValidatorFor(viewViewModel.Key, viewViewModel.Value);
            ValidationResult validatorResult = validator.Validate();
            yield return validatorResult;
        }
    }
}

This class validate a IDictionary<Type, Type>, the key is the “View” type, and the value is the ViewModel type. The View must have a public constructor without args, this test will create an instance of the View. The ViewModel type could be a class, could be abstract and even an interface!

The test is really easy, if you are using Caliburn, you already have a IViewStrategy. The Chinook Media Manager use a convention based approach and I don’t have an special artifact for this purpose. So my test looks as follows:

 

[TestFixture]
public class TestDataBindings
{
    private static Type GetViewForViewModel(Type viewModelType)
    {
        string viewName = viewModelType.Name.Replace("ViewModel", "View");
        string viewFullName = 
            string.Format("ChinookMediaManager.GUI.Views.{0}, ChinookMediaManager.GUI", 
            viewName);
        Type viewType = Type.GetType(viewFullName, true);
        return viewType;
    }

    [Test]
    public void AllDatabindingsAreOkay()
    {
        bool fail = false;
        var databindingValidator = new DataBindingValidator();

        Type examplePresenterType = typeof(AlbumManagerViewModel);

        var dictionary = examplePresenterType
                .Assembly.GetTypes()
                .Where(type => type.Namespace.EndsWith("ViewModels"))
                .ToDictionary(vmType => GetViewForViewModel(vmType), 
                              vmType => vmType);

        

        foreach (var validationResult in databindingValidator.Validate(dictionary))
        {
            if(validationResult.HasErrors)
            {
                Console.WriteLine(validationResult.ErrorSummary);
                fail = true;
            }
        }

        fail.Should().Be.False();
    }
}

If you have any error in your databinding this test will fail. This test also show you a list of the DataBinding errors in the console, and for each error the full path inside the View:

image

You can see here the “nesting level”, Album is a property of the EditAlbumViewModel, Title is a property in the Album type. Titlo doesn’t exist. EditAlbumView.Grid.TextBox is the full xaml path to the control holding the databinding. It show Grid and TextBox because these elements doesn’t have a name in xaml.

This is why I use Caliburn.Testability in Chinook Media Manager.

| More

Note: I owe this knowledge to my friend Fabio Maulo, so I would like to thank him for teaching me and letting me share.

Introduction

I will show you in this post a nice way to configure your IoC container and some other aspects of your applications. I assume for this article that you have good knowledge of dependency injection and inversion of control.

The problem

There was a time when we used to configure our containers with xml, and all was fine. Then we started to use fluent and strongly typed interfaces and a problem became more frequent and acute. Basically, when we use a fluent interface, we do something like this:

container.Register(Component.For<IAlbumRepository>()
                       .ImplementedBy<AlbumRepository>()
                       .LifeStyle.Transient);

IAlbumRepository is in Chinook.Data and AlbumRepository is in Chinook.Data.Impl. 
The problem is not *how* but *where*. Where do you do this?

Most people will say “The startup project”. One of the goal that we look when using IoC is:

..decoupling of the execution of a certain task from implementation.

Pay attention to the “Decoupling” part. If you want “decoupling”: Why do you add all those references in your startup project?

This is a NDepend extracted graph of the Northwind example that comes with Sharp Architecture:

 

If you look at the Northwind.Web assembly you will see that it has a reference even to NHibernate. It has a reference to Northwind.Data (repositories that use NHibernate). The contract interface of repositories is in Northwind.Core. Also you can see that the start up project need a reference to Castle Container. If I want a loosely coupled solution, I don’t want some of those references.

Pay atention; the northwind example of Sharp Architecture is a very good example, is a good architecture, and this is neither a complain nor a criticism. I’m pretty sure that it defines interfaces and implementations separately, as I’m pretty sure that controllers depends upon IRepositories. But, I think it has a problem at reference level. The main problem is because the initialization of the container is in a wrong place. You could see the initialization script here.

So, what I’m looking for is:

  • I don’t want references to concrete implementations in my startup project.
  • I don’t want to depend upon a specific IoC container technology.
  • And finally I don’t want to configure my container in the startup project, its is another “aspect” of my application like the repositories!

The Solution

The solution is very simple. Take the container initialization to another place.

We used to call this place “The GuyWire”, in italian “Cavo Portante”, in spanish “Cable Maestro”:

A guy-wire or guy-rope is a tensioned cable designed to add stability to structures

Two simple rules to remember:

  1. In order to configure service and implementers fluently, the GuyWire will reference everything.
  2. Because the guy-wire reference everything, the GuyWire can not be referenced.

The guywire is an excellent place to “configure” the whole application. I used to separate the configuration in different aspects. Here some examples:

  • ORM configuration
  • Constraint Validator configuration
  • Repositories configuration
  • Entities configuration
  • ViewModel configuration
  • Controllers configuration
  • Views configuration

You can explore the configurators of ChinookMediaManager here.

How does it works?

The guywire project has an special “Output Path”:

image

So, the path is the “Startup” project.

Secondly, in the App.Config, I have a config like this:

<appSettings>
  <add key="GuyWire" value="ChinookMediaManager.GuyWire.GeneralGuyWire, ChinookMediaManager.GuyWire" />
</appSettings>

And finally, in my App.Xaml.cs:

public partial class App : Application
{
    private readonly IGuyWire guyWire = ApplicationConfiguration.GetGuyWire();

    public App()
    {
        guyWire.Wire();
    }
    
    protected override void OnStartup(StartupEventArgs e)
    {
        var viewFactory = ServiceLocator.Current.GetInstance<IViewFactory>();
        viewFactory.ShowView<BrowseArtistViewModel>();
    }

    protected override void OnExit(ExitEventArgs e)
    {
        guyWire.Dewire();
        base.OnExit(e);
    }
}

The interface IGuyWire and other classes needed for doing this, are in unhaddins.

The dependency graph of the Chinook Media Manager is:

image

Image taked with NDepend.

A last word about the Configurators

I really like the idea of have different parts of the application configuration in separated classes. I used to reuse this configurators alone in my Tests. But, as a I said before, the guywire should not be referenced by any project. So, my trick is add the configurator as a “linked file” to the test project:

image

And this is a sample:

private IWindsorContainer container;

[TestFixtureSetUp]
public void FixtureSetUp()
{
    container = new WindsorContainer();
    var configurator = new NHVConfigurator();
    configurator.Configure(container);
}

[Test]
public void title_constraints()
{
    GetConstraint<Album, NotEmptyAttribute>(a => a.Title)
        .Message
        .Should().Be.EqualTo("Title should not be null.");

    GetConstraint<Album, LengthAttribute>(a => a.Title)
        .Should().Be.OfType<LengthAttribute>()
        .And.ValueOf.Message.Should()
        .Be.EqualTo("Title should not exceed 200 chars.");
        
    
}

I will not talk about this long break in the series. If you are interested in Wpf and Nhibernate, you should be happy because; I'M BACK!

| More

A menudo veo en el foro de NHibernate hispano que alguien pregunta como manejar la session de NHibernate en aplicaciones WEB, o algunas otras preguntas raras como si es necesario algún framework para manejar la session.

Sea ASP.NET o ASP.Net MVC el patrón que solemos usar es session-per-request. En este post voy a comentar como yo suelo hacer esto.

Las 50 primeras páginas las voy a dedicar pura y exclusivamente a la teoría:

Session y Transaction tienen igual ciclo de vida que un web request.

Recordar que NHibernate ya dispone de una forma de manejar sesiones de contexto, y la que vamos a usar es “managed_web”.  entonces lo único que tenemos que hacer en nuestro archivo de configuración de NHibernate es lo siguiente:

<property name="current_session_context_class">managed_web</property>

De esta forma le estamos diciendo a nhibernate que vamos a utilizar ese contexto. La particularidad de ese “manejador” de contexto es que guarda la session actual en un HttpContext.

Luego en el código lo único que tenemos que hacer es lo siguiente:

public class Global: System.Web.HttpApplication
{
    public static ISessionFactory SessionFactory 
                            = CreateSessionFactory();
    
    protected static ISessionFactory CreateSessionFactory()
    {
        return new Configuration()
            .Configure()
            .BuildSessionFactory();
    }
    
    
    protected void Global()
    {
        BeginRequest += (sender, args) => 
        {
                var session = Session.OpenSession()
                ManagedWebSessionContext.Bind(
                        HttpContext.Current,
                        session);
                session.BeginTransaction();

        };
        EndRequest += (sender, args) => 
        {
                ISession session = ManagedWebSessionContext.Unbind(
                                HttpContext.Current, SessionFactory);
                if (session != null)
                {
                    if (session.Transaction != null &&
                        session.Transaction.IsActive)
                    {
                        session.Transaction.Commit();
                    }
                    session.Close();
                }
        };
    }
}

Si la aplicación tiene mucho contenido que no necesita acceder a la persistencia, como páginas estáticas haría una pequeña modificación allí para que no inicie una transacción por cada request.

Como acceder a la Session desde nuestros repositorios o daos, es muy sencillo:

namespace SGF.Data.Impl.Repositories
{
    public class Dao<T> : IDao<T>
    {
        private readonly ISessionFactory _factory;

        public Dao(ISessionFactory factory)
        {
            _factory = factory;
        }

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

        #region IDao<T> Members

        public T Get(object id)
        {
            return Session.Get<T>(id);
        }

        public T GetProxy(object id)
        {
            return Session.Load<T>(id);
        }

        public T Save(T entity)
        {
            Session.Save(entity);
            return entity;
        }

        // and so on..

    }
}

Nuestros DAO’s dependen de ISessionFactory, dado que en el constructor esperan un ISessionFactory. Casi nunca construyo un DAO manualmente siempre lo hace mi IoC container… Pero eso son 200 páginas más.

| More