José F. Romaniello

Las aventuras y desventuras de un codificador.

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

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

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

 

How does this work?

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

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

How to use the hql files?

You can read the full guide here.

Where do I get this?

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

Provide feedback is mandatory

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

| More

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

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

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

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

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

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

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

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

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

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

3-How to get an instance of a given type

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

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

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

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

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

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

Ok, this is all for now.

Advantages of QueryableServiceLocator over CommonServiceLocator

There are two big advantages:

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

TODOs

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

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

 

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

Ideas?

| More