Try fast search NHibernate

16 October 2010

Sharp Tests Ex 1.1.0 RTM

Sharp Tests Ex 1.1.0 RTM was released today.

Mayor changes are related to some internal matters and references to specific framework.

Now you can use SharpTestsEx even to test your Silverlight4 applications.

Download it and : Happy testing!!!

15 October 2010

ConfORMando NHibernate 3

El dia 2 de Noviembre estaré presenciando una charla en el auditorium del MUG (Microsoft Users Group) de Buenos Aires, Rivadavia 1479 1º A.


Ver mapa más grande

La intencción es la de mostrar un uso “distinto” de NHibernate.

Para asistir no se necesita ninguna experiencia previa con NHibernate y si nunca lo han usado verán cuan simple es su uso. Si ya están usando NHibernate, aunque sea desde varios años, verán algo nuevo... no creo que se vayan a aburrir.

El evento es gratuito y pueden registrarse desde aquí.
Los espero.

11 October 2010

TURBO NHibernate with domain invaders

The idea of this post have started at the local Buenos Aries CodeCap 2010 where I have attended : “In loving by Entity Framework”… well at that moment my nice girlfriend was at home. I saw a really nice girl… well… they have shown me her face and a big nice dress that covered the entire body ... I asked to see her in a bikini but it was not possible.
Seriously (I’ll try) the question to myself was: can we take some advantage, from a code generator, creating those fat POCOs ?
I know that some of my posts may seems does not have sense… to find some hidden gems in NHibernate is not so easy ;-)

Puorte 'e cazune cu nu stemma arreto...na cuppulella cu 'a visiera aizata...

public class PocoEntity
{
    public virtual Guid Id { get; set; }
    public virtual string Description { get; set; }
}

Tu vuo’ fa’ ll’americano…sient'a mme chi t' 'o ffa fa'?

public class SelfTrackingEntity : INotifyPropertyChanged
{
    private string description;
    public virtual Guid Id { get; set; }

    public virtual string Description
    {
        get { return description; }
        set
        {
            if (value != description)
            {
                description = value;
                NotifyPropertyChanged("Description");
            }
        }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

    private void NotifyPropertyChanged(string info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

Ok, I have the two entities, and now I can start the proof of concept.
I’ll fill the DataBase with one thousand instances for each entity, then I’ll upload 1000 instances of each, all in one session, I’ll modify few (only 10 entities) and then I’ll flush the session tracking the time of the flush. In other words:

[TestFixtureSetUp]
public void DbCreation()
{
    nhinit = new NHibernateInitializer();
    nhinit.Initialize();
    nhinit.CreateSchema();
    sf = nhinit.SessionFactory;
    FillDb();
}

public void FillDb()
{
    using (var s = sf.OpenSession())
    using (var tx = s.BeginTransaction())
    {
        for (int i = 0; i < 1000; i++)
        {
            s.Persist(new PocoEntity { Description = "pocoValue" + i });
        }
        tx.Commit();
    }

    using (var s = sf.OpenSession())
    using (var tx = s.BeginTransaction())
    {
        for (int i = 0; i < 1000; i++)
        {
            s.Persist(new SelfTrackingEntity { Description = "SelfTrackingEntityValue" + i });
        }
        tx.Commit();
    }
}

[Test]
public void TimeToFlushPocoEntities()
{
    using (var s = sf.OpenSession())
    using (var tx = s.BeginTransaction())
    {
        var entities = s.QueryOver<PocoEntity>().List();
        var someToModify = entities.Skip(4).Take(10);
        foreach (var entity in someToModify)
        {
            entity.Description = "Modified";
        }
        var stopWath = new Stopwatch();
        stopWath.Start();
        tx.Commit();
        stopWath.Stop();
        Console.WriteLine("Milliseconds to flush and commit:" + stopWath.ElapsedMilliseconds);
    }          
}

[Test]
public void TimeToFlushSelfTrackingEntities()
{
    using (var s = sf.OpenSession())
    using (var tx = s.BeginTransaction())
    {
        var entities = s.QueryOver<SelfTrackingEntity>().List();
        var someToModify = entities.Skip(4).Take(10);
        foreach (var entity in someToModify)
        {
            entity.Description = "Modified";
        }
        var stopWath = new Stopwatch();
        stopWath.Start();
        tx.Commit();
        stopWath.Stop();
        Console.WriteLine("Milliseconds to flush and commit:" + stopWath.ElapsedMilliseconds);
    }
}

 

Tu abball' o' rocchenroll tu giochi a baisiboll... ma e solde p' e' Ccamel chi te li dá ?

The result ?

For POCO entities: 72 Milliseconds
For entities with INotifyPropertyChanged : 11 Milliseconds

The difference is really big (auto-dirty-check is 7 times slower), but the unit of measurement is not (milliseconds).

Tu vuo' fa' ll'americano ma si' nato in Italy!

How much code I wrote to have this result ?
what about this ?
  1. [Serializable]
  2. public class PostLoadEventListener : IPostLoadEventListener
  3. {
  4.     public void OnPostLoad(PostLoadEvent @event)
  5.     {
  6.         var trackableEntity = @event.Entity as INotifyPropertyChanged;
  7.         if(trackableEntity != null)
  8.         {
  9.             EntityEntry entry = @event.Session.PersistenceContext.GetEntry(@event.Entity);
  10.             entry.BackSetStatus(Status.ReadOnly);
  11.             entry.BackSetTracer(new EntityTracer(entry, trackableEntity));
  12.         }
  13.     }
  14. }
  15.  
  16. public class EntityTracer
  17. {
  18.     public EntityTracer(EntityEntry entry, INotifyPropertyChanged trackableEntity)
  19.     {
  20.         trackableEntity.PropertyChanged += (sender, e) => entry.BackSetStatus(Status.Loaded);
  21.     }
  22. }
  23.  
  24. [Serializable]
  25. public class PreDeleteEventListener : IDeleteEventListener
  26. {
  27.     public void OnDelete(DeleteEvent @event)
  28.     {
  29.         OnDelete(@event, new IdentitySet());
  30.     }
  31.  
  32.     public void OnDelete(DeleteEvent @event, ISet transientEntities)
  33.     {
  34.         var session = @event.Session;
  35.         EntityEntry entry = session.PersistenceContext.GetEntry(@event.Entity);
  36.         if (entry != null && entry.RowId is EntityTracer)
  37.         {
  38.             entry.BackSetStatus(Status.Loaded);
  39.         }
  40.     }
  41. }

 

sient' a mme: nun ce sta niente 'a fa' ok, napulitan!

This was only a proof of concept, perhaps it has memory leaks, perhaps I have used some nasty tricks… but it works.
Now is the time to apply some very little little changes in NHibernate core to allow a more easy implementation of this and others possible features.
P.S.: the sound track is available here.

08 October 2010

Castle Windsor InstantiateAndForgetIt Lifestyle

Directly to the point.

The case

public interface IMySingleton : IDisposable
{
}

public class MySingleton: IMySingleton
{
    public void Dispose()
    {
    }
}

public interface IMyTransient
{
}

public class MyTransient : IMyTransient
{
    private readonly IMySingleton singleton;

    public MyTransient(IMySingleton singleton)
    {
        this.singleton = singleton;
    }
}
As you can see it is pretty common: I have a class MyTransient with a dependency from a singleton. The singleton is disposable.
The transient is from the point of view of its usage, that mean that its lifecycle is managed by an “external context” and, as is, it does not need a special “destructor”. The “external context” may hold the instance somewhere or may use it only in the context of a method and can quite leave the destruction to the garbage collector. If/when MyTransient implements IDisposable the “external context” should dispose the instance. You can see this behavior in various places for example in the DefaultControllerFactory of Asp.NET MVC or in the IInstanceProvider of WCF (both has a ReleaseInstance cheking for IDisposable); personally I have this situation in other places.
If I do something like this
var myInstance = new MyTransient(container.Resolve<IMySingleton>());
The garbage collector will have zero problems to destroy myInstance and I’ll have zero memory leaks… that is clear, no ?

The test using Windsor with Transient Lifestyle

public class TransientLeak
{
    private WindsorContainer GetContainerConfiguredWindsorContainer()
    {
        var container = new WindsorContainer();
        container.Register(Component.For<IMySingleton>().ImplementedBy<MySingleton>());
        container.Register(Component.For<IMyTransient>().ImplementedBy<MyTransient>().LifeStyle.Transient);
        return container;
    }

    [Test]
    public void WhenTransientRequiredThenReturnDifferentInstances()
    {
        using (WindsorContainer container = GetContainerConfiguredWindsorContainer())
        {
            var t0 = container.Resolve<IMyTransient>();
            var t1 = container.Resolve<IMyTransient>();

            t0.Should().Not.Be.SameInstanceAs(t1);
        }
    }

    [Test]
    public void WhenTransientRequiredThenContainerShouldntHaveInstancesOfMyTransient()
    {
        using (WindsorContainer container = GetContainerConfiguredWindsorContainer())
        {
            var t0 = container.Resolve<IMyTransient>();
            var t1 = container.Resolve<IMyTransient>();

            container.Kernel.ReleasePolicy.Satisfy(rp=> !rp.HasTrack(t0));
            container.Kernel.ReleasePolicy.Satisfy(rp => !rp.HasTrack(t1));
        }
    }     
}
Well… the first test pass, that means that each time I asking for a IMyTransient I’ll have a new instance of the concrete implementation injected with the same instance of IMySingleton (as expected).

Now take care : The second test fails. That means that the container is holding two instances of MyTransient class; let me show you where:
TransientLeak
Perhaps there is a good explication for this behavior but I must admit that I can’t understand why all instances of MyTransient should have its lifecycle stuck to the lifecycle of MySingleton only because MySingleton is disposable… bah?!? by the way that is not a matter because Castle.Windsor give us the ability to define the behavior we need.

The solution

First of all I need my custom lifestyle manager:
[Serializable]
public class InstantiateAndForgetIt : ILifestyleManager
{
    private IComponentActivator componentActivator;

    public void Init(IComponentActivator componentActivator, IKernel kernel, ComponentModel model)
    {
        this.componentActivator = componentActivator;
    }

    public object Resolve(CreationContext context)
    {
        return componentActivator.Create(context);
    }

    public bool Release(object instance)
    {
        return true;
    }

    public void Dispose()
    {
     
    }
}

Pretty simple but not enough. Then I need an implementation of IReleasePolicy and I can simply inherit from the default and override a method:
[Serializable]
public class LifecycledComponentsReleasePolicy : Castle.MicroKernel.Releasers.LifecycledComponentsReleasePolicy
{
    private readonly Type instantiateAndForgetItType = typeof (InstantiateAndForgetIt);

    public override void Track(object instance, Burden burden)
    {
        if (instantiateAndForgetItType.Equals(burden.Model.CustomLifestyle))
        {
            return;
        }
        base.Track(instance,burden);
    }
}

The last step is the modification of the container’s configuration:
private WindsorContainer GetContainerConfiguredWindsorContainer()
{
    var container = new WindsorContainer();
    container.Kernel.ReleasePolicy = new LifecycledComponentsReleasePolicy();
    container.Register(Component.For<IMySingleton>().ImplementedBy<MySingleton>());
    container.Register(Component.For<IMyTransient>().ImplementedBy<MyTransient>().LifeStyle.Custom<InstantiateAndForgetIt>());
    return container;
}


Work done!! and bye bye “memory leaks”.


Update: request to have InstantiateAndForgetIt Lifestyle natively supported issue IOC-225 (vote for it)

05 October 2010

NHibernate 3.0 Cookbook.

This week Packt published the NHibernate 3.0 Cookbook. Packt are offering all members of the NHibernate community 20% off the book.
The book helps users to get solutions to common NHibernate problems to develop high-quality performance-critical data access applications.
The book, which is 328 pages long, contains quick-paced self-explanatory recipes organized in progressive skill levels and functional areas.
Overview of NHibernate 3.0 Cookbook
  • Master the full range of NHibernate features
  • Reduce hours of application development time and get better application architecture and performance
  • Create, maintain, and update your database structure automatically with the help of NHibernate
  • Written and tested for NHibernate 3.0 with input from the development team distilled in to easily accessible concepts and examples
  • Part of Packt's Cookbook series: each recipe is a carefully organized sequence of instructions to complete the task as efficiently as possible
Is this book for you?
This book is written for NHibernate users at all levels of experience. Examples are written in C# and XML. Some basic knowledge of SQL is assumed.
To get your exclusive 20% discount when you buy through PacktPub.com, just enter the discount code NHIBCBK20 (case sensitive), to the shopping cart.
Click here to read more about the NHibernate 3.0 Cookbook.