José F. Romaniello

Las aventuras y desventuras de un codificador.

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

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

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

2010-07-25_1011

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

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

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

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

2010-07-27_0845

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

| More

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

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

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

The first interface is the “Albums Browser”:

myImage

And the second interface is the “Album Editor”:

myImage (1)

 

So, I have two concerns in this scenario:

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

So, I will declare two events:

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

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


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

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

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

EventAggregator.Publish(new AlbumUpdated(id));

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

But we need two kind of subscription mechanism.

Instance Subscription

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

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

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

Type Subscription

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

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

    //...
}

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

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

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

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

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

| More