José F. Romaniello

Las aventuras y desventuras de un codificador.

You know, like “from Rusia with love”, this is the Criolla version.

Well, I was talking with my friend Fabian Figueredo from YoProgramo.net about specification pattern and compositions with Linq and then I figure out a nice idea that I will use soon.

If you read my blog, I’m using often the Dao pattern, with the interface described by Fabio Maulo here . The interface has these two major methods:

IEnumerable<TEntity> Retrieve(Expression<Func<TEntity, bool>> predicate);
int Count(Expression<Func<TEntity, bool>> predicate);

This interface is really nice and allows me to build code like this:

dao.Retrieve(Customers.Prefered())
dao.Retrieve(Customers.WithoutActivitySince(new DateTime(2009, 12, 01)))

These kind of queries are easy to write. The problem comes when you want to operate queries, let say apply boolean operators.

What if we want:

  • Prefered customers without activity since a specific date.
  • Prefered customers with activity since a specific date.
  • Not prefered customers without activity since a specific date.

So, the problem is that we have our specifications objects, but we need to operate.

Note: I have seen a project linq-specifications, but it seems to not help with this task.

The solution

Imagine an in-memory (fake) dao of strings:

public class SampleRepository : ReadOnlyCollection<string>, IDaoQueryable<string>
{
    public SampleRepository() : base(new []{"Jose", "Manuel", "Julian"})
    {}

    public IEnumerable<string> Retrieve(Specification<string> specfication)
    {
        return this.AsQueryable().Where(specfication.Spec());
    }
}

The tests:

[Test]
public void adhoc_should_work()
{
    var specification = new AdHocSpecification<string>(n => n.StartsWith("J"));

    var result = new SampleRepository()
                        .Retrieve(specification);

    result.Satisfy(r => r.Contains("Jose")
                      && r.Contains("Julian")
                      && !r.Contains("Manuel"));
}

[Test]
public void negate_should_work()
{
    var specification = new NegateSpecification<string>(n => n.StartsWith("J"));

    var result = new SampleRepository()
                        .Retrieve(specification);

    result.Satisfy(r => !r.Contains("Jose")
                      && !r.Contains("Julian")
                      && r.Contains("Manuel"));
}

[Test]
public void and_should_work()
{
    var startWithJ = new AdHocSpecification<string>(n => n.StartsWith("J"));
    var endsWithE = new AdHocSpecification<string>(n => n.EndsWith("e"));

    var result = new SampleRepository()
                        .Retrieve(startWithJ & endsWithE);

    result.Satisfy(r => !r.Contains("Jose")
                      && !r.Contains("Julian")
                      && r.Contains("Manuel"));
}


[Test]
public void or_should_work()
{
    var startWithJ = new AdHocSpecification<string>(n => n.StartsWith("J"));
    var endsWithN = new AdHocSpecification<string>(n => n.EndsWith("n"));

    var result = new SampleRepository()
                        .Retrieve(startWithJ | endsWithN);

    result.Satisfy(r => r.Contains("Jose")
                      && r.Contains("Julian")
                      && !r.Contains("Manuel"));
}

[Test]
public void combination_sample_should_work()
{
    var startWithJ = new AdHocSpecification<string>(n => n.StartsWith("J"));
    var endsWithN = new AdHocSpecification<string>(n => n.EndsWith("n"));
    

    var result = new SampleRepository()
                        .Retrieve(startWithJ | !endsWithN);
        
    result.Satisfy(r => r.Contains("Jose")
                      && !r.Contains("Julian")
                      && !r.Contains("Manuel"));
}

As you can see I want binary operators &, | , and !.

The solution:

public abstract class Specification<T>
{
    public abstract Expression<Func<T, bool>> Spec();

    public static Specification<T> operator &(Specification<T> spec1, Specification<T> spec2)
    {
        return new AndSpecification<T>(spec1.Spec(), spec2.Spec());
    }

    public static Specification<T> operator |(Specification<T> spec1, Specification<T> spec2)
    {
        return new OrSpecification<T>(spec1.Spec(), spec2.Spec());
    }
    public static Specification<T> operator !(Specification<T> spec1)
    {
        return new NegateSpecification<T>(spec1.Spec());
    }
}

public class AdHocSpecification<T> :Specification<T>
{
    private readonly Expression<Func<T, bool>> _specification;

    public AdHocSpecification(Expression<Func<T, bool>> specification)
    {
        _specification = specification;
    }

    public override Expression<Func<T, bool>> Spec()
    {
        return _specification;
    }
}
public class AndSpecification<T> : Specification<T>
{
    private readonly Expression<Func<T, bool>> _spec1;
    private readonly Expression<Func<T, bool>> _spec2;

    public AndSpecification(Expression<Func<T, bool>> spec1, Expression<Func<T, bool>> spec2)
    {
        _spec1 = spec1;
        _spec2 = spec2;
    }

    public override Expression<Func<T, bool>> Spec()
    {
        ParameterExpression param = Expression.Parameter(typeof(T),"x");
        return Expression.Lambda<Func<T, bool>>(
            Expression.AndAlso(
                Expression.Invoke(_spec1, param), 
                Expression.Invoke(_spec2, param)), param);
    }
}

public class OrSpecification<T> : Specification<T>
{
    private readonly Expression<Func<T, bool>> _spec1;
    private readonly Expression<Func<T, bool>> _spec2;

    public OrSpecification(Expression<Func<T, bool>> spec1, Expression<Func<T, bool>> spec2)
    {
        _spec1 = spec1;
        _spec2 = spec2;
    }

    public override Expression<Func<T, bool>> Spec()
    {
        ParameterExpression param = Expression.Parameter(typeof(T), "x");
        return Expression.Lambda<Func<T, bool>>(
            Expression.OrElse(
                Expression.Invoke(_spec1, param),
                Expression.Invoke(_spec2, param)), param);
    }
}

public class NegateSpecification<T> : Specification<T>
{
    private readonly Expression<Func<T, bool>> _expression;

    public NegateSpecification(Expression<Func<T, bool>> expression)
    {
        _expression = expression;
    }

    public override Expression<Func<T, bool>> Spec()
    {
        ParameterExpression param = Expression.Parameter(typeof(T), "x");
        return Expression.Lambda<Func<T, bool>>(Expression.Not(Expression.Invoke(_expression, param)), param);
    }
}

Note:

  • I’ve defined the three operators in the base class for specifications.
  • Lambda expressions are lazy-constructed.

The AdHoc, And, Or and Negate specification are not meant to be used directly.  You must write your own specifications inheriting from Specification<T> and then you can operate when needed.

That said; I don’t write specifications for less important queries

Less important note: Yes this work with Nhibernate Linq (criteria version) and should work with EF.

var spec1 = new AdHocSpecification<Person>(p => p.FirstName.StartsWith("A"));
var spec2 = new AdHocSpecification<Person>(p => p.LastName.StartsWith("A"));

using(var s = sf.OpenSession())
using (var tx = s.BeginTransaction())
{
    s.Save(new Person {FirstName = "Alberto", LastName = "Arnaldo"});
    tx.Commit();
}

using(var s = sf.OpenSession())
using(var tx = s.BeginTransaction())
{
    var result = s.Linq<Person>().Where((spec1 & spec2).Spec());
    result.Count().Satisfy(r => r == 1);
    tx.Commit();
}

The generated sql query is:

21:01:55,906 DEBUG SQL:0 - SELECT count(*) as y0_ FROM Person this_ WHERE (this_.FirstName like @p0 and this_.LastName like @p1);@p0 = 'A%', @p1 = 'A%'

| More

I started to write a review about Ayende Rahien’s sample application Effectus, but I soon realized that what  I do better is to write code. So, this is an unconventional review, because I will focus on some parts of the code, and then show you the alternative.

You can read more about Effectus in Ayende Rahien’s blog.

Straight to the point

In this post I will focus only in the presenters of Effectus. Because this is the first thing that I don’t like.

private void LoadPage(int page)
{
    using (var tx = StatelessSession.BeginTransaction())
    {
        var actions = StatelessSession.CreateCriteria<ToDoAction>()
            .SetFirstResult(page * PageSize)
            .SetMaxResults(PageSize)
            .List<ToDoAction>();

        var total = StatelessSession.CreateCriteria<ToDoAction>()
            .SetProjection(Projections.RowCount())
            .UniqueResult<int>();

        this.NumberOfPages.Value = total / PageSize + (total % PageSize == 0 ? 0 : 1);
        this.Model = new Model
        {
            Actions = new ObservableCollection<ToDoAction>(actions),
            NumberOfPages = NumberOfPages,
            CurrentPage = CurrentPage + 1
        };
        this.CurrentPage.Value = page;

        tx.Commit();
    }
}

Ah? StatelessSession?, BeginTransaction?, CreateCriteria?. This presenter is GLUED to NHibernate. And this means for instance that you can’t test it without NHibernate, and this means that you can’t change your persistence layer.

So, pay attention to Conversation per Business Transaction. Fabio Maulo did a great job with this and I really like it.

Main\Presenter

Ayende’s code

namespace Effectus.Features.Main
{
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using Effectus.Model;
    using Events;
    using Infrastructure;
    using NHibernate.Criterion;
 
    public class Presenter : AbstractPresenter<Model, View>
    {
        const int PageSize = 3;
 
        public Observable<int> NumberOfPages { get; set; }
 
        public Observable<int> CurrentPage { get; set; }
 
        public Presenter()
        {
            NumberOfPages = new Observable<int>();
            CurrentPage = new Observable<int>();
 
            EventPublisher.Register<ActionUpdated>(RefreshCurrentPage);
        }
 
        private void RefreshCurrentPage(ActionUpdated _)
        {
            LoadPage(CurrentPage);
        }
 
        public Fact CanMovePrev
        {
            get { return new Fact(CurrentPage, 
                        () => CurrentPage > 0); }
        }
 
        public Fact CanMoveNext
        {
            get { return new Fact(CurrentPage, 
                        () => CurrentPage + 1 < NumberOfPages); }
        }
 
        public void OnCreateNew()
        {
            Presenters.Show("CreateNew");
        }
 
        public void OnActionsChoosen(ToDoAction action)
        {
            Presenters.Show("Edit", action.Id);
        }
 
        public void OnLoaded()
        {
            LoadPage(0);
        }
 
        public void OnMoveNext()
        {
            LoadPage(CurrentPage + 1);
        }
 
        public void OnMovePrev()
        {
            LoadPage(CurrentPage - 1);
        }
 
        private void LoadPage(int page)
        {
            using (var tx = StatelessSession.BeginTransaction())
            {
                var actions = StatelessSession
                    .CreateCriteria<ToDoAction>()
                    .SetFirstResult(page * PageSize)
                    .SetMaxResults(PageSize)
                    .List<ToDoAction>();
 
                var total = StatelessSession
                       .CreateCriteria<ToDoAction>()
                    .SetProjection(Projections.RowCount())
                    .UniqueResult<int>();
 
                this.NumberOfPages.Value = 
                        total / PageSize + (total % PageSize == 0 ? 0 : 1);
                this.Model = new Model
                {
                    Actions = new ObservableCollection<ToDoAction>(actions),
                    NumberOfPages = NumberOfPages,
                    CurrentPage = CurrentPage + 1
                };
                this.CurrentPage.Value = page;
 
                tx.Commit();
            }
        }
    }
}

My code

using System.Linq;
using Effectus.DataAccess;
using uNhAddIns.Adapters;

namespace Effectus.Features.Main
{
    using System.Collections.ObjectModel;
    using Effectus.Model;
    using Events;
    using Infrastructure;

    [PersistenceConversational(
        DefaultEndMode = EndMode.End, 
        MethodsIncludeMode = MethodsIncludeMode.Explicit)]
    public class Presenter : AbstractPresenter<Model, View>
    {
        private readonly IReadOnlyDao<ToDoAction> _toDoActionsDao;
        const int PageSize = 3;

        public Observable<int> NumberOfPages { get; set; }

        public Observable<int> CurrentPage { get; set; }

        public Presenter(IReadOnlyDao<ToDoAction> toDoActionsDao)
        {
            _toDoActionsDao = toDoActionsDao;
            NumberOfPages = new Observable<int>();
            CurrentPage = new Observable<int>();

            EventPublisher.Register<ActionUpdated>(RefreshCurrentPage);
        }

        [PersistenceConversation]
        public virtual void RefreshCurrentPage(ActionUpdated _)
        {
            LoadPage(CurrentPage);
        }

        public Fact CanMovePrev
        {
            get { return new Fact(CurrentPage, 
                            () => CurrentPage > 0); }
        }

        public Fact CanMoveNext
        {
            get { return new Fact(CurrentPage, 
                            () => CurrentPage + 1 < NumberOfPages); }
        }

        public void OnCreateNew()
        {
            Presenters.Show("CreateNew");
        }

        public void OnActionsChoosen(ToDoAction action)
        {
            Presenters.Show("Edit", action.Id);
        }

        [PersistenceConversation]
        public virtual void OnLoaded()
        {
            LoadPage(0);
        }
        
        [PersistenceConversation]
        public virtual void OnMoveNext()
        {
            LoadPage(CurrentPage + 1);
        }

        [PersistenceConversation]
        public virtual void OnMovePrev()
        {
            LoadPage(CurrentPage - 1);
        }

        private void LoadPage(int page)
        {
            var actions = _toDoActionsDao.RetrieveAll()
                                         .Skip(page * PageSize)
                                         .Take(PageSize).ToList();

            var total = _toDoActionsDao.RetrieveAll().Count();
            
            NumberOfPages.Value = total / PageSize 
                                + (total % PageSize == 0 ? 0 : 1);
            
            Model = new Model
            {
                Actions = new ObservableCollection<ToDoAction>(actions),
                NumberOfPages = NumberOfPages,
                CurrentPage = CurrentPage + 1
            };
            
            CurrentPage.Value = page;
        }
    }
}

There are two things that you will notice:

  • A dependency with IReadonlyDao<ToDoAction>. I will show you later the code for daos.
  • Conversation per business transactions attributes. These attributes are from a separated assembly unrelated to nhibernate. This means that we could implement this for EntityFramework or other ORM and the presenter is not coupled to the persistence framework. This will pass the “acid” test, thanks Angel “Java” Lopez.

Ah, there is a last thing about that code. There is a bug with the current page number.

AbstractPresenter

Ayende’s Code

namespace Effectus.Infrastructure
{
    using System;
    using System.Windows;
    using NHibernate;

    public abstract class AbstractPresenter<TModel, TView> : IDisposable, IPresenter
        where TView : Window, new()
    {
        private TModel model;
        private ISessionFactory sessionFactory;
        private ISession session;
        private IStatelessSession statelessSession;

        protected AbstractPresenter()
        {
            View = new TView();
            View.Closed += (sender, args) => Dispose();
        }

        DependencyObject IPresenter.View { get { return View; } }

        public object Result { get; protected set; }

        protected TView View { get; set; }

        protected ISessionFactory SessionFactory
        {
            get { return sessionFactory; }
        }

        protected ISession Session
        {
            get
            {
                if (session == null)
                    session = sessionFactory.OpenSession();
                return session;
            }
        }

        protected IStatelessSession StatelessSession
        {
            get
            {
                if (statelessSession == null)
                    statelessSession = sessionFactory.OpenStatelessSession();
                return statelessSession;
            }
        }

        protected TModel Model
        {
            get { return model; }
            set
            {
                model = value;
                View.DataContext = model;
            }
        }

        protected void ReplaceSessionAfterError()
        {
            if(session!=null)
            {
                session.Dispose();
                session = sessionFactory.OpenSession();
                ReplaceEntitiesLoadedByFaultedSession();
            }
            if(statelessSession!=null)
            {
                statelessSession.Dispose();
                statelessSession = sessionFactory.OpenStatelessSession();
            }
        }

        protected virtual void ReplaceEntitiesLoadedByFaultedSession()
        {
            throw new InvalidOperationException(
                @"ReplaceSessionAfterError was called, but the presenter does not override ReplaceEntitiesLoadedByFaultedSession!
You must override ReplaceEntitiesLoadedByFaultedSession to call ReplaceSessionAfterError.");
        }


        public void SetSessionFactory(ISessionFactory theSessionFactory)
        {
            sessionFactory = theSessionFactory;
        }

        public void Show()
        {
            View.Show();
        }

        public void ShowDialog()
        {
            View.ShowDialog();
        }

        public event Action Disposed = delegate { };

        public virtual void Dispose()
        {
            if(session!=null)
                session.Dispose();
            if (statelessSession != null)
                statelessSession.Dispose();
            View.Close();
            Disposed();
        }
    }
}

My code

namespace Effectus.Infrastructure
{
    using System;
    using System.Windows;
    using NHibernate;

    public abstract class AbstractPresenter<TModel, TView> : IDisposable, IPresenter
        where TView : Window, new()
    {
        private TModel model;

        protected AbstractPresenter()
        {
            View = new TView();
            View.Closed += (sender, args) => Dispose();
        }

        DependencyObject IPresenter.View { get { return View; } }

        public object Result { get; protected set; }

        protected TView View { get; set; }

        protected TModel Model
        {
            get { return model; }
            set
            {
                model = value;
                View.DataContext = model;
            }
        }

        public void Show()
        {
            View.Show();
        }

        public void ShowDialog()
        {
            View.ShowDialog();
        }

        public event Action Disposed = delegate { };

        public virtual void Dispose()
        {
            View.Close();
            Disposed();
        }

        public virtual void OnException(Exception exception)
        {
            //TODO You should improve this.
            MessageBox.Show(exception.Message);
        }
    }
}

Again, I’ve deleted all NHibernate code.

Edit\Presenter

Ayende’s code

namespace Effectus.Features.Edit
{
    using System;
    using System.Windows;
    using Effectus.Model;
    using Events;
    using Infrastructure;
    using Merge;
    using NHibernate;

    public class Presenter : AbstractPresenter<Model, View>
    {
        public Presenter()
        {
            EventPublisher.Register<ActionUpdated>(RefreshAction);
        }

        private void RefreshAction(ActionUpdated actionUpdated)
        {
            if (actionUpdated.Id != Model.Action.Id)
                return;
            Session.Refresh(Model.Action);
        }

        public void Initialize(long id)
        {
            ToDoAction action;
            using (var tx = Session.BeginTransaction())
            {
                action = Session.Get<ToDoAction>(id);
                tx.Commit();
            }

            if (action == null)
                throw new InvalidOperationException("Action " + id + " does not exists");

            this.Model = new Model
            {
                Action = action
            };
        }
        [PersistenceConversation(ConversationEndMode = EndMode.Abort)]
        public void OnCancel()
        {
            View.Close();
        }

        public void OnCreateConcurrencyConflict()
        {
            using (var session = SessionFactory.OpenSession())
            using (var tx = session.BeginTransaction())
            {
                var anotherActionInstance = session.Get<ToDoAction>(Model.Action.Id);
                anotherActionInstance.Title = anotherActionInstance.Title + " - ";
                tx.Commit();
            }
            MessageBox.Show("Concurrency conflict created");
        }

        public void OnSave()
        {
            bool successfulSave;
            try
            {
                using (var tx = Session.BeginTransaction())
                {
                    // this isn't strictly necessary, NHibernate will 
                    // automatically do it for us, but it make things
                    // more explicit
                    Session.Update(Model.Action);

                    tx.Commit();
                }
                successfulSave = true;
            }
            catch (StaleObjectStateException)
            {
                var mergeResult = Presenters.ShowDialog<MergeResult?>("Merge", Model.Action);
                successfulSave = mergeResult != null;

                ReplaceSessionAfterError();
            }

            // we call ActionUpdated anyway, either we updated the value ourselves
            // or we encountered a concurrency conflict, in which case we _still_
            // want other parts of the application to update themselves with the values
            // from the db
            EventPublisher.Publish(new ActionUpdated
            {
                Id = Model.Action.Id
            }, this);

            if (successfulSave)
                View.Close();
        }

        protected override void ReplaceEntitiesLoadedByFaultedSession()
        {
            Initialize(Model.Action.Id);
        }
    }
}

There are several things with the OnSave method that I don’t like:

  • ReplaceSessionAfterError, to much responsibility for a presenter.
  • Session/Transaction again.
  • There is a BUG, the publish mechanism work in sync with the rest of the code. This means… that this windows is not going to close until others have finished handling the event. For the given example, the Edit windows is not going to close until the main window finish to refresh the current page.
  • Too much logic for this method = hard to test.

My code

using Effectus.DataAccess;
using Effectus.Features.Merge;
using Effectus.Infrastructure.Bootstrapping;
using Effectus.Infrastructure.ConversationsArtifacts;
using uNhAddIns.Adapters;
using uNhAddIns.SessionEasier.Conversations;

namespace Effectus.Features.Edit
{
    using System;
    using System.Windows;
    using Effectus.Model;
    using Events;
    using Infrastructure;
    using NHibernate;

    [PersistenceConversational(
            DefaultEndMode = EndMode.Continue, 
            UseConversationCreationInterceptorConvention = true)]
    public class Presenter : AbstractPresenter<Model, View>
    {
        private readonly IDao<ToDoAction> _toDoActionsDao;

        public Presenter(IDao<ToDoAction> toDoActionsDao)
        {
            _toDoActionsDao = toDoActionsDao;
            EventPublisher.Register<ActionUpdated>(RefreshAction);
        }
        
        [PersistenceConversation]
        public virtual void RefreshAction(ActionUpdated actionUpdated)
        {
            if (actionUpdated.Id != Model.Action.Id)
                return;

            _toDoActionsDao.Refresh(Model.Action);
        }

        [PersistenceConversation]
        public virtual void Initialize(long id)
        {
            var action = _toDoActionsDao.GetById(id);

            if (action == null)
                throw new InvalidOperationException("Action " + id + " does not exists");

            Model = new Model
            {
                Action = action
            };
        }

        public void OnCancel()
        {
            View.Close();
        }

        public void OnCreateConcurrencyConflict()
        {
            //NOTE: this portion of code is for generating a conflict.
            //don't use sessionfactory in presenters.

            var sessionFactory = BootStrapper.Container.Resolve<ISessionFactory>();

            using (var session = sessionFactory.OpenSession())
            using (var tx = session.BeginTransaction())
            {
                var anotherActionInstance = session.Get<ToDoAction>(Model.Action.Id);
                anotherActionInstance.Title = anotherActionInstance.Title + " - ";
                tx.Commit();
            }
            MessageBox.Show("Concurrency conflict created");
        }

        [PersistenceConversation(ConversationEndMode = EndMode.End)]
        public virtual void OnSave()
        {
            _toDoActionsDao.Update(Model.Action);

            EventPublisher.Enlist(new ActionUpdated
            {
                Id = Model.Action.Id
            }, this);

            View.Close();
        }

        public override void OnException(Exception exception)
        {
            if(exception is StaleEntityException)
            {
                Presenters.ShowDialog<MergeResult?>("Merge", Model.Action);

                EventPublisher.Enlist(new ActionUpdated
                {
                    Id = Model.Action.Id
                }, this);

            }
        }
    }

}

Pay atention:

  • I’ve defined a new convention, if a public method in the presenter throw an exception, the OnException method will be called. This is done by a castle interceptor, and this is the last line of defense for unhandled exceptions.
  • I’m using “StaleEntityException” rather than “StaleObjectStateException”, this is MY exception. This is easily done by a CpBT artifact.
  • I’m not calling “EventPublisher.Publish” anymore, this code use EventPublisher.Enlist. Here, I’ve split the “Publish” code in two different methods one for Enlist and other for Raise. The enlisted events will be raised right after the OnSave method is called and thus after the windows is closed.
  • Also, notice that here is the conversation per business transaction pattern with all its splendor. The two former methods are conversation participants, with EndMode equals to continue. This means that the NH Session will remain opened. The OnSave method has EndMode equals to End, this means that right after the method finished, CpBT internally will flush the Unit of Work and close it.

 

The code needed for exception interception:

public class RecoverableExceptionIntercepter : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        if(!typeof(ISupportExceptionRecovery).IsAssignableFrom(invocation.TargetType))
        {
            throw new NotSupportedException(string.Format("{0} should implement {1}", 
                invocation.TargetType.Name, 
                typeof(ISupportExceptionRecovery).Name));
        }

        try
        {
            invocation.Proceed();
        }catch(Exception ex)
        {
            var recoverablePresenter = (ISupportExceptionRecovery) invocation.InvocationTarget;
            recoverablePresenter.OnException(ex);
        }

    }
}

The code needed for auto-flushing published events:

public class AutoFlushEventPublisherEvents : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        invocation.Proceed();
        EventPublisher.FlushEvents((IPresenter) invocation.InvocationTarget);
    }
}

The code for daos

Interfaces:

public interface IReadOnlyDao<T>
    where T : EntityBase 
{
    T GetById(object id);
    T GetProxy(object id);
    IEnumerable<T> Retrieve(Expression<Func<T, bool>> predicate);

    int Count(Expression<Func<T, bool>> predicate);

    /// <summary>
    /// Retrieve all entities.
    /// </summary>
    /// <returns></returns>
    IEnumerable<T> RetrieveAll();
}

public interface IDao<T> : IReadOnlyDao<T>
    where T : EntityBase 
{
    void Save(T entity);
    void Update(T entity);
    void Delete(T entity);
    
    /// <summary>
    /// Re-read the state of the given instance from the underlying database.
    /// </summary>
    /// <param name="entity"></param>
    void Refresh(T entity);

    /// <summary>
    /// Merge the instance in to the persisted instance of the current unit of work.
    /// </summary>
    /// <param name="entity"></param>
    void Merge(T entity);

}

These interfaces were taken from Fabio Maulo’s post “Repository or DAO”?: Dao.

Implementation:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Effectus.Model;
using NHibernate;
using NHibernate.Criterion;
using NHibernate.Linq;

namespace Effectus.DataAccess
{
    public class Dao<T> : IDao<T>
        where T : EntityBase
    {
        private readonly ISessionFactory _sessionFactory;

        public Dao(ISessionFactory sessionFactory)
        {
            _sessionFactory = sessionFactory;
        }

        private IQueryable<T> CurrentLinq
        {
            get { return ContextSession.Linq<T>(); }
        }

        private ISession ContextSession
        {
            get { return _sessionFactory.GetCurrentSession(); }
        }

        #region IDao<T> Members

        public void Save(T entity)
        {
            ContextSession.Save(entity);
        }

        public void Update(T entity)
        {
            ContextSession.Update(entity);
        }

        public void Delete(T entity)
        {
            ContextSession.Delete(entity);
        }

        public void Refresh(T entity)
        {
            ContextSession.Refresh(entity);
        }

        public void Merge(T entity)
        {
            ContextSession.Merge(entity);
        }

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

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

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

        public IEnumerable<T> RetrieveAll()
        {
            return CurrentLinq;
        }

        public int Count(Expression<Func<T, bool>> predicate)
        {
            return CurrentLinq.Count(predicate);
        }

        #endregion
    }

    
}

Download

Here is the full code. Maybe someone help me to “fork” github version, this will be very nice to make code diff.

The end

There is nothing more, I like very much the result of this review and I will be waiting your comments (please let me a comment). I hope you like it!

| More

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

Según nos comenta Fabio Maulo, hoy fue liberada la versión 2.1.1GA de NHibernate, lo que a mi criterio es el mejor Framework de ORM sobre la plataforma .Net.

Hace mucho tiempo que vengo posteando en este blog algunas experiencias que tengo con NHibernate.

Qué estas esperando a descargarlo!

| More

Una de las cosas que aprendí de NHibernate.Validator hoy es que puedo definir una constraint en una interface. Y como no encontré mucha información quería comentar lo que hice con un ejemplo típico de mi negocio. (Por cierto al no haber nada en google puedo estar totalmente equivocado)

En el dominio de aplicaciones contables, a menudo nos encontramos con un tipo de estructura que yo llamo “Balanceable”. Balanceable significa que el movimiento debe cerrar, equilibrar, balancear.

Por ejemplo, un asiento contable, tiene que sumar igual importe en su Haber que en su Debe. En un flujo de caja, debe entrar a una o varias cajas el mismo monto que sale de otra/s. Extendiendo este concepto más allá, un movimiento de mercaderías debe descontar la misma cantidad de un depósito que lo que suma en otros. A este punto creo que ya se entiende el dominio.

La interface IBalanceable tiene esta pinta:

public interface IBalanceable
{
    bool EstaBalanceado { get; }
}

La definición de la constraint, usando fluent, es como sigue:

public class BalanceableValidationDef : ValidationDef<IBalanceable>
{
    public BalanceableValidationDef()
    {
        Define(b => b.EstaBalanceado)
            .IsTrue()
            .WithMessage("La entidad no balancea.");
    }
}

Una clase que implementa balanceable es la siguiente:

public class AsientoContable 
        : BaseEntity, IBalanceable
{
    //...un monton de código.
    
    public virtual IList<AsientoContableLinea> 
                Lineas { get; private set; }

    public bool EstaBalanceado
    {
        get
        {
            return Lineas
                .Sum(x => x.Importe * x.Signo.ToValue()) 
                    == 0;
        }
    }
}

Y el test es algo así:

[Test]
public void CuandoAsientoNoBalancea_ViolacionDeConstraint()
{
    var asiento = new AsientoContable();
    asiento.AgregarLinea(new AsientoContableLinea
                             {
                                 Importe = 1000, 
                                Signo = Signo.Debe
                             });
    asiento.GetErrors()
        .Satisfy(c => 
    c.Any(e => e.Message.Equals("La entidad no balancea.")));
    
}

Para los que no estan acostumbrados al estilo de Satisfier (es decir SharpTestEx), el test se lee así: “de este asiento dame los errores, esa colección de errores debe SATISFACER la condición de tener ALGÚN mensaje de error cuya descripción sea igual a “La entidad no balancea”. GetErrors es un extension method que usa IEntityValidator, en algún momento posteare acerca de eso.

La conclusión de este ejemplo, es que a partir de ahora, todo lo que sea IBalanceable tendrá esa constraint que yo definí una sola vez.

Por otro lado, recordar que este es el segundo ejemplo que posteo en español, con el tag MundoReal, esto quiere decir que son ejemplos donde el dominio no es un invento de mi imaginación :D. El primero fue un caso de monedas.

| More

En las reuniones familiares o de amigos, siempre hay 3 o 4 preguntas que seguro alguien nos hace a nosotros “los informáticos”:
-Me aparece un mensaje de error!!! en mi compu que puedo hacer donde esta el virus?
-Qué computadora me tengo que comprar?
-Qué juego conoces?

Realmente esas preguntas no me dan ganas de contestar, además yo soy programador y desconozco la respuesta. Pero en algún momento de la reunión, puede llegar el momento filosófico de la cuestión… Y en ese momento alguien puede disparar esta pregunta, que en mi caso me encanta contestar:

La computadora puede superar o va a superar a la mente humana?

La respuesta como a muchas cosas es “depende”, pero a mi me gusta hablar (característica que compartimos los argentinos)

  • Mi computadora guarda aproximadamente 120 gigas de información y yo no puedo recordar el número de teléfono de mi esposa.
  • Mi computadora puede realizar cálculos bastantes complejos que a mi me llevarían días.. o años.
  • Gracias a la computadora podemos resolver problemas que de otra forma no solo nos costaría mucho trabajo, si no que algunos si quiera podríamos.

Si alguien hubiese preguntado si las computadoras llegarían a este nivel, en la época que estas estaban en pañales, la respuesta probablemente hubiera sido NO.

Paradójicamente, a veces las tareas simples son las mas complicadas; una persona normal al año de vida es capaz de diferenciar entre un perro y un gato apenas viendo alguna parte de la imagen. El solo tratar de pensar en la complejidad de la red neuronal y el entrenamiento necesario me da escalofríos. Tratar de hacer que una computadora realice esta tarea, es algo muy difícil, mas no imposible.

Jimi, mi perro - my dog por Rod Chile 

Si le interesan estos temas puede leer un libro viejito llamado “La era de las máquinas espirituales”.

| More

In this post I will introduce a project under Unofficial NHibernate Addins named ComponentBehaviors. The goal of this project is to inject some goodness of System.ComponentModel through a dynamic proxy framework.

The WHY

Sometimes you need to implement certain interfaces of ComponentModel, for various reasons such as DataBinding, but the code need to accomplish this is tedious and repetitive. This code is called "plumbing code", an the following snippet is an example:

public class Customer : BaseEntity
{
    private string _firstName;
    public virtual string FirstName
    {
        get { return _firstName; }
        set
        {
            if(!_firstName.Equals(value))
            {
                _firstName = value;
                OnPropertyChanged("FirstName");
            }
        }
    }

    private string _lastName;
    public virtual string LastName
    {
        get { return _lastName; }
        set
        {
            if(!_lastName.Equals(value))
            {
                _lastName = value;    
                OnPropertyChanged("LastName");
            }
        }
    }
}

In the above sample, a property declaration took me 12 lines of code. Why I can't use auto properties (1 line)?

My goal was to have the same functionality like the above but with the following code:

public class Customer
{
    public virtual string FirstName {get; set;}
    public virtual string LastName {get; set;}
}

//Somewhere

configuration.For<Customer>()
    .Add<NotifiableBehavior>()
    .Add<DataErrorInfoBehavior>()
    .Add<EditableBehavior>();

A side effect is that classes are not tied to those interfaces and can be used in another project.

The WHAT

By now there are three supported behaviors:

  • DataErrorInfoBehavior
  • EditableBehavior
  • NotifyPropertyChangedBehavior

DataErrorInfo Behavior

The DataErrorInfo behavior is based on the interface IDataErrorInfo, and is described by me in this post. The configuration is as follows:

configuration.For<Customer>()
.Add<DataErrorInfoBehavior>();

You need to plug in your container an IEntityValidator, fortunately we have four implementations in uNhAddIns:

  • NHibernate Validator
  • DataAnnotations
  • Application Validation Block
  • Castle Validations

You can read more in this post of Fabio Maulo.

IDataErrorInfo is described in MSDN :

Provides the functionality to offer custom error information that a user interface can bind to.

Almost any DataBinding infrastructures such as Asp.Net, Asp.Net MVC, Winforms and WPF supports binding to an IDataErrorInfo entity.

Editable Behavior

The Editable behavior is based on the interface IEditableObject. The goal of this behavior is described in MSDN as follows:

Provides functionality to commit or rollback changes to an object that is used as a data source.

Note: Commit or Rollback refers to in-memory operations. Not database.

So a test like this, is self-explanatory:

[Test]
public void session_shouldnot_be_dirty_after_cancelchanges()
{
    var id = CreateNewAlbum();
    using (ISession session = sessions.OpenSession())
    using (ITransaction tx = session.BeginTransaction())
    {
        var album = session.Get<Album>(id);
        ((IEditableObject) album).BeginEdit();
        album.Title = "Dark side of the moon";
        ((IEditableObject) album).CancelEdit();
        session.IsDirty().Should().Be.False();

        tx.Commit();
    }
}

NotifyPropertyChanged behavior

NotifyPropertyChanged behavior is based on the interface INotifyPropertyChanged and is very well described in the MSDN:

The INotifyPropertyChanged interface is used to notify clients, typically binding clients, that a property value has changed.

The WHERE

With uNhAddIns.ComponentBehaviors you define the behaviors of a class ONCE and you can get an entity with the behaviors in many ways. I will describe in this section how ComponentBehaviors works with NHibernate.

Transient Entities

We just need an IEntityFactory in our projects as follows:

public class EntityFactory : IEntityFactory
{
    private readonly IComponentProxyFactory _componentProxyFactory;

    public EntityFactory(IComponentProxyFactory componentProxyFactory)
    {
        _componentProxyFactory = componentProxyFactory;
    }

    public T CreateInstance<T>()
    {
        return (T) _componentProxyFactory.GetEntity(typeof (T));
    }
}

Just plug that in your container and now you will be able to inject an IEntityFactory in your services.

Persisted entities

There are two ways to tell NHibernate that every time we return an object, this must come with the behaviors. The first way is with an interceptor as follows:

nhibernateConfig.Interceptor = 
    container.Resolve<ComponentBehaviorInterceptor>();

The second is has a little overhead because it involves to inject your entities in the container and now I'm using vaguely. But you can read more in this thread.

Proxy entities

With the steps described in the previous section, whenever nhibernate return an object, this object will come with the behaviors. But what happen when NHibernate itself need to generate a proxy for lazyloading stuff? Well, we can even specify that we want our behaviors in those proxies.

And the configuration is very easy:

cfg.Properties[Environment.ProxyFactoryFactoryClass] = 
    typeof (ComponentProxyFactoryFactory)
        .AssemblyQualifiedName

 

Final thoughts

If you want to see a working applications that use those concepts, have a look to this example.

I’ve started this project because I need it for my job, this was my first serious experience developing open source and for me has been very positive:

  • I’ve talked with lot of people around the globe, open source developers or not.
  • Some of them are using the library and improving.
  • I’ve learned a lot of Castle DynamicProxy and NHibernate.
  • I’ve participated in the afore mentioned projects.
  • I’ve three new job offers.

A word about NHibernate

For me, one of the interesting things that I found in NHibernate is a lot of “extensions points”. You could plug whatever you want and radically change the behavior of the tool to fit your needs.

Enjoy the NHibernate injection. :-)

| More

Note; this is an English version of my original post.

A few days ago I found a bug in Moq, the Mock framework I am currently using. I had a feeling for the stack trace of the exception was a DynamicProxy error, knowing that Moq uses DynamicProxy Castle and knowing a little DynamicProxy, I decided to investigate Moq inside.

The first thing I did was write a test in Moq that fail, but guess what, this is a very rare type of error related to the Visual Studio debugger, so if the debugger is not hooked, the error does not occur. The second thing I did was to isolate the problem to DynamicProxy, and that's when I really realized it was directly related to DynamicProxy. Then try to reproduce the problem in the trunk of dynamicproxy version, which obviously is not what my Moq version was using. And failed. Everything I have said to this point has been with some help from my friend from Poland, Krzysztof Kozmic. But here is where my involvement with the story ends. And you can read the whole thread here.

I’ve opened then the issue DP-115, and this is where the work of Krzysztof begins. He commented, that along the way, he found bugs on:

  • Reflector
  • Resharper
  • And finally this appears to be a bug in the debugger.

I can only imagine the complexity of the work of Krzysztof. I come closely following the footsteps of Krzysztof, simply because I'm passionate to learning about this subject. I have seen wonderful things like this, which is practically the backstage of DynamicProxy ... In 35 lines of code, my friend has created a type, inheriting an interface, has defined the generics methods of the interface with constraints, has created an assembly and saved the assembly. WAW!

Congratulations to Krzysztof for his amazing job, and thank you for the sparks that let us learn!, now he can read this post that was originally wrote in Spanish.

| More

Hace unos días encontré un error en Moq, el framework de Mock que estoy usando actualmente. Tuve un presentimiento por el stack trace de la excepción que era un error de DynamicProxy, sabiendo que Moq utiliza DynamicProxy de Castle y conociendo un poco DynamicProxy, decidí investigar Moq por dentro.

Lo primero que hice fue escribir un test en Moq que fallará, pero adivine qué?, este es un tipo de error muy raro relacionado al debugger de visual studio, así que si el debugger no esta “enganchado”, el error no aparece. Lo segundo que hice fue aislar el problema a DynamicProxy, y ahí fue cuando realmente me di cuenta que estaba directamente relacionado con DynamicProxy. Acto seguido, intente reproducir el problema en la versión trunk de dynamicproxy, que evidentemente no es la que estaba usando mi versión de Moq. Y también fallaba. Todo lo que he comentado hasta este punto ha sido con alguna ayuda de mi amigo de Polonia, Krzysztof Kozmic. Pero en este punto es donde mi participación en la historia termina. Y se puede leer todo el hilo acá.

A partir de que cargo el caso DP-115 es donde empieza a actuar directamente Krzysztof. Según nos comenta, por la complejidad del error, en su camino a descubrirlo a encontrado bugs en:

  • Reflector
  • Resharper
  • Y parece que finalmente es un error en el debugger.

Imaginó que este trabajo es muy duro ya que implica revisar incluso como ciertas cosas son compiladas. Vengo siguiendo muy de cerca los pasos de Krzysztof, simplemente por que me apasiona aprender. He visto cosas tan maravillosas como esta, es practicamente lo que DynamicProxy hace tras bambalinas… En 35 líneas de código, mi amigo ha creado un tipo, heredando una interfaz, ha definido su métodos genérico con constraints, ha generado un ensamblado dinámicamente, ha guardado el ensamblado. WAW!

Desde ya felicitaciones a Krzysztof. Seguramente él no va a entender nada de este post por que esta en español, a menos que use un traductor.

| More

I will try to explain a way to mock a linq based Dao, as the one introduced by Fabio Maulo here. The interface of the dao is something like this:

public interface IDao<TEntity{
//....
IEnumerable<TEntity> Retrieve(Expression<Func<TEntity, bool>> predicate);

int Count(Expression<Func<TEntity, bool>> predicate);
}

Suppose you have a controller or service, and you want to test a method is using a proper predicate for load the invoices of a given month and year. I’m using Moq for this example:

daoInvoices
    .Setup(dao => dao.Retrieve(Par.IsAnyPredicateOf<Invoice>()))
    .Returns(new List<Invoices> {newInvoice})
    .Callback<Expression<Func<Invoice, bool>>>(
predicate =>
    {
        predicate.Evaluate(invoiceIn)
                .Should().Be.True();

        predicate.Evaluate(invoiceOut)
                .Should().Be.False();
    }
);

Why I’m doing this?, Why validate the predicate in the callback? Because you can't match Expressions . You can read more info here, Moq isn’t exempt of this fact. So, my mock ignores the parameter, but the parameter is checked in the callback.

Evaluate(..) is an extension method for Expressions:

public static class ExpressionsExtensions
{
    public static bool Evaluate<T>(this Expression<Func<T,bool>> expression, T value)
    {
        return expression.Compile()(value);
    }
}

the expression is compiled twice, so?..
Par.IsAnyPredicateOf is another helper:

public static class Par
{
    public static Expression<Func<T, bool>> IsAnyPredicateOf<T>()
    {
        return It.IsAny<Expression<Func<T, bool>>>();
    }
}

"It" comes from Moq.

And maybe this is out of topic but I’m not testing the query itself!!!!!!!!. The query should be tested against the database, and if is possible, the real one. I tend to define my queries in a separated place, so queries are declared as follows:

namespace MyXYZSuperProject.Domain.Predicates
{
    public static class Invoice
    {
        public static Expression<Func<Invoice, bool>> 
                        ByPeriod(int month, int year)
        {
            return invoice => 
                            invoice.Month == month 
                            && recupero.Year == year;
        }
    }
}

Month and year are stored properties in this case, be careful.
AND I didn’t say NHibernate in the whole post!

| More

IMPORTANT NOTE: this code won’t work with WPF. Send me a patch :)

I just make a proof of concept with dynamics, and this is the result.

[TestMethod]
public void should_work()
{
    dynamic obj = new MyNotifiableExpandoObject();
    bool wasRaised = false;

    ((INotifyPropertyChanged)obj).PropertyChanged 
        += (sender, arg) => 
        {
            wasRaised = true;
            arg.PropertyName.Should().Be.EqualTo("Name");
        };

    obj.Name = "José";
    wasRaised.Should().Be.True;
}
 

I'm using C# 4 and the new keyword dynamic, MyNotifiableExpandoObject is a class that inherits from this one, first I tried to use ExpandoObject but.. is sealed.

So, my notifiable expando object is as follows:

public class MyNotifiableExpandoObject  : MyExpando, INotifyPropertyChanged
{
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler eventHandler = PropertyChanged;
        if (eventHandler != null) eventHandler(this, new PropertyChangedEventArgs(propertyName));
    }

    public override bool  TrySetMember(SetMemberBinder binder, object value)
    {
        var result = base.TrySetMember(binder, value);
        OnPropertyChanged(binder.Name);
        return result;
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler  PropertyChanged;

    #endregion
}

I hope you like it. Now ever property you set the propertychanged event will be raised properly.

| More

I will show you a trivial example of mixins with LinFu in this post.
Note: this is the first time I use LinFu stuff.

Sample Scenario

We have a Customer class as follows:

public class Customer
{
    public virtual int Id { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
}

And we have a customer repository that looks as follows:

public interface ICustomerRepository
{
    ICollection<Customer> GetSomeCustomers();
}

Now, we have a user case in WPF, that needs to display the Customer data, but we need an extra bool property named “Selected”, this property will be bound to some checkbox in the GUI. How to solve this, without a CustomerDTO nor SelectableCustomer class?

Mixins

First we start with this:

public interface ISelectable
{
    bool Selected { get; set; }
}

public class Selectable : ISelectable
{
    #region ISelectable Members

    public virtual bool Selected { get; set; }

    #endregion
}

Now, I will create an extension method named “AsSelectable”, this is my test case:

[TestFixture]
public class SelectableTestFixture
{
    [Test]
    public void as_selectable_works()
    {
        var list = new List<Customer>
                       {
                           new Customer {FirstName = "José", LastName = "Romaniello"},
                           new Customer {FirstName = "Juan", LastName = "Perez"},
                           new Customer {FirstName = "Pedro", LastName = "Picolli"}
                       };
        List<Customer> customerList = list.AsSelectable().ToList();

        customerList[0].FirstName.Should().Be.EqualTo("José");
        ((ISelectable) customerList[0]).Selected.Should().Be.False();

        customerList[1].FirstName.Should().Be.EqualTo("Juan");
        ((ISelectable) customerList[1]).Selected.Should().Be.False();
    }
}

And this is the code for AsSelectable with LinFu 1.0:

public static class AsSelectableExtension
{
    private static readonly ProxyFactory refl = new ProxyFactory();

    public static IEnumerable<T> AsSelectable<T>(this IEnumerable<T> enumerable)
        where T : class
    {
        
        
        //Create a type that inherits from customer and implements ISelectable
        Type selectableCustomerType = refl.CreateProxyType(typeof (T), new[] {typeof (ISelectable)});

        foreach (T entity in enumerable)
        {
            var dynCustomer = new DynamicObject();
            dynCustomer.MixWith(entity);
            dynCustomer.MixWith(new Selectable());
            yield return (T) dynCustomer.CreateDuck(selectableCustomerType);
        }
    }
}

And for me… it looks very nice. I don’t know how to implement this with the current version of LinFu, I use the binaries from here.
This works great with WPF. I hope you like it.

| More

Gracias al comentario de Fabio Maulo, sobre mi anterior post fue que decidí escribir escribir este post.

Evidentemente si alguien decide enumerar el diccionario tendremos un serio problema, ya que como antes mencioné, 3650 no es chiste. Aunque es un tema de mal uso de la api debería restringirlo de alguna manera. Entonces estuve estos últimos cinco minutos pensando como solucionarlo, y me vinieron dos ideas a la cabeza.

1er Idea: Propiedad indexada en la clase moneda

En vez de publicar una propiedad del tipo IDictionary<DateTime, Cotizacion>, publicar una propiedad indexada, por lo cual mi clase Moneda pasaría a ser así:

public class Moneda
{
    public virtual int Id { get; protected set; }
    public virtual string Nombre { get; set; }
    private readonly IDictionary<DateTime, Cotizacion> _cotizaciones;
    public virtual Cotizacion this[DateTime fecha]
    {
        get
        {
            Cotizacion cotizacionBuscada;
            if (_cotizaciones.TryGetValue(fecha, out cotizacionBuscada))
                return cotizacionBuscada;
            throw new InvalidOperationException("No existe cotización para la fecha buscada.");
        }
        set
        {
            _cotizaciones[fecha] = value;
        }
    }

    public Moneda()
    {
        _cotizaciones = new Dictionary<DateTime, Cotizacion>();    
    }
}

Y cómo va a hacer NHibernate para colocar las cotizaciones en ese field PRIVADO?
Simple solo ponemos este tag en el mapeo de la collection:

access="field"

Problema solucionado, nunca más se podrán enumerar (desde afuera) la colection.

2da Idea: NotEnumerableDictionary

Esta opción se me vino a la cabeza en el caso de que quisiera mantener la misma sintaxis que antes.

Les presento mi NotEnumerableDictionary (lo lamento no encontré un nombre mejor):

public class NotEnumerableDictionary<TKey, TValue>
{
    private readonly IDictionary<TKey, TValue> _dictionary;

    public NotEnumerableDictionary(IDictionary<TKey,TValue> dictionary)
    {
        _dictionary = dictionary;
    }

    public virtual TValue this[TKey key]
    {
        get
        {
            return _dictionary[key];
        }
        set
        {
            _dictionary[key] = value;
        }
    }
}

Ahora la clase Moneda quedaría así:

public class Moneda
{
    public virtual int Id { get; protected set; }
    public virtual string Nombre { get; set; }
    private readonly IDictionary<DateTime, Cotizacion> _cotizaciones;

    public virtual NotEnumerableDictionary<DateTime,Cotizacion> Cotizaciones
    {
        get
        {
            return new NotEnumerableDictionary<DateTime, Cotizacion>(_cotizaciones);
        }
    }

    public Moneda()
    {
        _cotizaciones = new Dictionary<DateTime, Cotizacion>();    
    }
}

Y el mapeo es igual que en el primer ejemplo.

En los dos ejemplos, de ninguna forma se puede utilizar linq para consultar esa collection. La consulta de Fabio debería ejecutarse así:

moneda.Cotizaciones[DateTime.Today.AddDays(-7)]

| More