José F. Romaniello

Las aventuras y desventuras de un codificador.

I will show you in this post two tricks you can do to enhance and add value to your nhibernate logs.

Format Sql

This is widely know trick, you can add a configuration setting to your hibernate.cfg.xml, app.config or web.config as follow:

<property name="hibernate.format_sql" value="true" />

or you can simply do it in code:

config.DataBaseIntegration(db => db.LogFormatedSql = true)

with this trick you will get nicely formated sql in your logs files.

Logging the session identifier

All nice, we have a bunch of sql logs, but we don’t know which queries belongs to which sessions. This might be useful when you are debugging an application with multiples threads or requests.

I found this trick inside NHibernate, the easy way I found so far is to add a log4net appender like this one:

<appender name="NHibernateAppender" type="log4net.Appender.RollingFileAppender">
  <appendToFile value="true"/>
  <datePattern value="yyyyMMdd"/>
  <file value="./logs/NHibernate.log"/>
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date Session id: %property{sessionId} - %message%newline"/>
  </layout>
  <rollingStyle value="Date"/>
</appender>

See the %property{sessionId} in the conversion pattern?

Well, in order to log something there you need to do two steps.

Add a class like this one:

public class SessionIdCapturer
{
    public override string ToString()
    {
        return SessionIdLoggingContext.SessionId.ToString();
    }
}

Add the following code in some place at the application initialization:

ThreadContext.Properties["sessionId"] = new SessionIdCapturer();

That is all! I found this code inside a nhibernate test.. it is something not very known.

After doing so, your logs will look like:

2011-05-05 18:35:59,899 Session id: 5e172068-5064-44b6-bf96-99362ca05c46 - 
    SELECT
        myFoo0_.AccountId as AccountId3_0_,
        myFoo0_.Name as Name3_0_,
        myFoo0_.Version as Version3_0_ 
    FROM
        MyFoo myFoo0_
    WHERE
        myFoo0_.AccountId=@p0;
    @p0 = 1 [Type: Int32 (0)]

Another way to have this information (and much more) is to use the nhprof tool.

| More

If you follow my tweets for sure you had read one of these:

2011-05-04_1343

2011-05-04_1343_001

2011-05-04_1345

This is one of the things I most enjoy of working for Tellago. The Tellago Technology Dojo is a webinar that we have once a week to talk about new technologies. Which is a high quality webinar from qualified developers.

Today Tellago announced a series of webinars named “Tellago Technology Updates”, from Jesús Rodriguez blog:

Today, we are really pleased to announce the Tellago Technology Updates series. This program is a periodic series of webinar that will explore in detail debate some of the emerging technologies in the software industry as well as some of our implementation experiences. These Technology Updates are targeted to both IT executives trying to adopt these new technologies as well as developers and architects trying to implement them.

You can follow the Technology Updates series at http://tellago.com/what_we_says/tellago-technology-updates

BOTTOM LINE, WHETHER YOU ARE AN IT EXECUTIVE, ARCHITECT OR DEVELOPER INTERESTED ON UNDERSTANDING SOME OF THESE TECHNOLOGIES, YOU SHOULD NOT MISS THE TELLAGO TECHNOLOGY UPDATES SERIES!!!!!

The first two webinars announced are:

  • NOSQL DATABASES FOR THE .NET DEVELOPER: WHAT’S THE FUSS ALL ABOUT?
  • I LIKE IPHONE AND ANDROID BUT I AM A .NET DEVELOPER: DEVELOPING .NET APPLICATIONS FOR IPHONE AND ANDROID
You can read more about these webinars in our brand new website!
Those webinars are completely free and open to anyone.
If you missed, you will be able to watch the recording offline.

We hope to see you there!

| More

I have created a new package that add support for writing NHibernate logs with NLog.
The package is not a dll but only one class.

In order to use this package, simply install with nuget:

2011-05-04_0838

This is an example app.config file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
  </configSections>
  <appSettings>
    <add key="nhibernate-logger" value="YourNamespace.NLogFactory, YourAssemblyName"/>
  </appSettings>

  <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <targets>
      <target name="ds" xsi:type="Console"/>
    </targets>
    <rules>
      <logger name="NHibernate.SQL" minlevel="Debug" writeTo="ds" />
    </rules>
  </nlog>
</configuration>

Remember to change “YourNamespace” and “YourAssemblyName”. That is all.
You don’t need to run Configure or some initialization code as in log4net.

There is an alternative approach here but it is a little bit more complicated.

| More

In this post I will show how to enhance your REST services by providing cache headers in the responses. I am going to show a simple but scalable implementation in the new Wcf Web API; however the intention of this article is purely theoretically.

Introduction

As I am not good explaining things in English and most of the things are already explained, I will simply copy and paste the w3.org explanation for Http Cache:

HTTP is typically used for distributed information systems, where performance can be improved by the use of response caches. The HTTP/1.1 protocol includes a number of elements intended to make caching work as well as possible…

Caching would be useless if it did not significantly improve performance. The goal of caching in HTTP/1.1 is to eliminate the need to send requests in many cases, and to eliminate the need to send full responses in many other cases. The former reduces the number of network round-trips required for many operations; we use an "expiration" mechanism for this purpose (see section 13.2). The latter reduces network bandwidth requirements; we use a "validation" mechanism for this purpose

As the last quote say; the two more important things from HTTP cache is “expiration” and “validation”.
Remember; Http is everywhere and we can take tremendous advantage of the HTTP infrastructure.

Implementation

Lets say that I have a resource like this:

[ServiceContract, WithUriPrefix("order")]
public class OrderResourceHandler
{
    private readonly IRepository<Order> orderRepository;
    
    public OrderResourceHandler(
        IRepository<Order> orderRepository)
    {
        this.orderRepository = orderRepository
    }

    [WebGet(UriTemplate = "{orderId}")]
    public HttpResponseMessage Get(int orderId)
    {
        var order = orderRepository.GetById(orderId);
        if(order == null) return Response.NotFound();
        return Response.WithContent(new OrderRepresentation(order));
    }
}

In this example, every request will hit the handler, the repository, the database and so on. We can take advantage of the Web infrastructure by adding cache instructions to our response

A better implementation with cache headers will be something like this:

[ServiceContract, WithUriPrefix("order")]
public class OrderResourceHandler
{
    private readonly IRepository<Order> orderRepository;
    private readonly ETagCache etagCache;

    public OrderResourceHandler(
        IRepository<Order> orderRepository,
        ETagCache etagCache)
    {
        this.orderRepository = orderRepository
        this.etagCache = etagCache;
    }

    [WebGet(UriTemplate = "{orderId}")]
    public HttpResponseMessage Get(int orderId)
    {
        var order = orderRepository.GetById(orderId);
        if(order == null) return Response.NotFound();

        var response = Response.WithContent(new OrderRepresentation(order));
        AddCacheHeaders(response, order.Id, order.Version);
        return response;
    }

    private void AddCacheHeaders(HttpResponseMessage responseMessage, long orderId, int version)
    {
        //Get the link for the resource: http://mysuperapp.com/order/123
        var link = linker.GetUri<OrderResourceHandler>(orh => orh.Get(0), new { orderId });

        //Get or Add the Etag to the cache.
        var etag = etagCache.GetOrAdd(link, version);

        //Set the 'expiration' and 'validation' (maxage and etag)
        responseMessage.WithCacheControlHeader(c =>
                                {
                                    c.Public = true;
                                    c.MaxAge = TimeSpan.FromSeconds(10);
                                })
                       .WithETagHeader(etag);
    }

}

I choose using “Max-Age” for “expiration” and “ETag” for “validation”. But you can use other mechanism as “Expires” (for expiration) and “Last-Modified” (for validation) or any combination in the middle.

A quick overview to the method:

  • I introduced an ETagCache, this is a cache for the ETags.. The thing is that during conditional get (or validations get) I would like to respond as fast as possible. Even without going to the database. The cache consist of an uri as key and a version number (the actual etag value).
  • I am using as ETag a Version property. This version property is managed by my ORM for concurrency. Each update we do in the entity version increases by one.
  • As max-age I am using 10 seconds. This is only for experimental purposes.

This code add the cache headers to the response.

How we can handle conditional-gets (get for validations)?

Suppose that as an http client we receive a response as follows:

2011-04-27_1559

We, as an intelligent http client now that we can use this representation of the resource for 10 seconds. After those ten seconds, if we need again the representation we might send a conditional request, as follows:

2011-04-27_1605

And when we do such thing we know that two things might happen:

  • The resource has changed in those 10 seconds. So we will probably get a 200-OK response with the new representation of the resource.
  • The resource hasn’t changed, so we get a 302-Not Modified without any content. This means that we can keep using the previous representation that we hold.

I used an specific extension point from the last release of the WCF Web API to handle this, a DelegatingChannel:

public class EntityTagCheckerDelegateChannel : DelegatingChannel
{
    private readonly ETagCache etagCache;

    public EntityTagCheckerDelegateChannel(HttpMessageChannel innerChannel, ETagCache etagCache)
        : base(innerChannel)
    {
        this.etagCache = etagCache;
    }
    
    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        
        if(request.Method == HttpMethod.Get && request.Headers.IfNoneMatch.Any())
        {
            var etag = request.Headers.IfNoneMatch.First().ToString();
            var cached = etagCache.Get(request.RequestUri.ToString());
            return etag == cached ? Task.Factory.StartNew(() => CreateANotModifiedResponse(), 
                                                                cancellationToken)
                                : base.SendAsync(request, cancellationToken);
        }
        return base.SendAsync(request, cancellationToken);
    }

    private static HttpResponseMessage CreateANotModifiedResponse()
    {
        return new HttpResponseMessage(HttpStatusCode.NotModified, "NotModified")
                   {
                       Headers = {CacheControl = new CacheControlHeaderValue
                                                     {
                                                         MaxAge = TimeSpan.FromSeconds(10),
                                                         Public = true
                                                     }}
                   };
    }
}

If the request is a GET, and it contains an IfNoneMatch tag, we compare this with the one in our etagCache. If the tags match, we return a task that returns a NotModified with the same cache headers. If not, we proceed with the invocation to our handler.

When resources change

When the resource change we need to tell to our EtagCache the new value of the ETag. I did this within an extension point of my ORM (because my resource is something stored in a database):

public class OnOrderUpdateInsert : IPostInsertEventListener, IPostUpdateEventListener
{
    private readonly ETagCache etagCache;
    private readonly string baseAddress;
    
    public OnOrderUpdateInsert(EntityTagManager entityTagManager)
        : this(entityTagManager, ConfigurationManager.AppSettings["BaseUri"])
    {
    }

    public OnOrderUpdateInsert(ETagCache etagCache, string baseAddress)
    {
        this.etagCache = etagCache;
        this.baseAddress = baseAddress;
    }

    public void OnPostInsert(PostInsertEvent @event)
    {
        Handle(@event);
    }

    public void OnPostUpdate(PostUpdateEvent @event)
    {
        Handle(@event);
    }

    private void Handle(IPostDatabaseOperationEventArgs @event)
    {
        var entity = @event.Entity as Order;
        if (entity == null) return;
        var link = string.Format("{0}order/{1}", 
                            baseAddress, entity.Id);
        etagCache.Add(link, entity.Version);
    }
}

The ETagCache

The ETagCache is:

public class ETagCache
{
    private readonly ConcurrentDictionary<string, string> cache =
        new ConcurrentDictionary<string, string>();
    
    public void Add(string link, int version)
    {
        cache.AddOrUpdate(link, 
                ToETag(version), 
                (l, prev) => ToETag(version));
    }
    
    public string GetOrAdd(string link, int version)
    {
        return cache.GetOrAdd(link, ToETag(version));
    }

    private static string ToETag(int version)
    {
        return string.Format("\"{0}\"", version);
    }

    public string Get(string link)
    {
        string etag;
        return cache.TryGetValue(link, out etag) ? 
                etag : string.Empty;
    }
}

For now, it is implemented with only a ConcurrentDictionary.
This means that I am assuming that the database is not changed by anyone else than the rest service. Which is quite good for this example, but as soon as you need to change the orders outside this application you will be better of with other kind of ETag cache, with other expiration policy or so.

See the system working

I am using fiddler to test my service. A simple GET request:

#REQUEST

GET http://localhost:13509/order/294912 HTTP/1.1
User-Agent: Fiddler
Accept: text/xml
Host: localhost:13509


#RESPONSE

HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Wed, 27 Apr 2011 22:36:42 GMT
X-AspNet-Version: 4.0.30319
Content-Length: 844
Cache-Control: public, max-age=10
ETag: "1"
Content-Type: text/xml; charset=utf-8
Connection: Close

<?xml version="1.0" encoding="utf-8"?><order xmlns="....

now that we now the ETag, we can try a conditional get as follows:

#REQUEST

GET http://localhost:13509/order/294912 HTTP/1.1
User-Agent: Fiddler
Accept: text/xml
Host: localhost:13509
If-None-Match: "1"

#RESPONSE

HTTP/1.1 304 Not Modified
Server: ASP.NET Development Server/10.0.0.0
Date: Wed, 27 Apr 2011 22:39:40 GMT
X-AspNet-Version: 4.0.30319
Cache-Control: public, max-age=36000
Connection: Close

Urray! conditional gets work like a charm!

So, now we know that our http clients can validate caches with conditional requests.

Simulating a real world scenario

You can simulate a real world scenario (and potentially scale your application) by using a reverse-proxy (or application proxy), from wikipedia:

In computer networks, a reverse proxy is a type of proxy server that retrieves resources on behalf of a client from one or more servers. These resources are then returned to the client as though it originated from the reverse proxy itself.[1] While a forward proxy is usually situated between the client application (such as a web browser) and the server(s) hosting the desired resources, a reverse proxy is usually situated closer to the server(s) and will only return a configured set of resources.

To simulate a simple scenario, I am using the powerfull squid-cache. If you want to run in your own follow these steps:

  • download the windows version from one of the links..
  • copy etc\mime.conf.default to etc\mime.conf
  • copy squid.conf.default to squid.conf
  • delete all the content of squid.conf.default and add the following:
access_log C:\squid\var\logs\access_log.txt
http_port 3128 accel defaultsite=mysite.com
cache_peer localhost parent 13509 0 no-query originserver name=myAccel

#Recommended minimum configuration:
acl all src all
acl manager proto cache_object
acl localhost src 127.0.0.1/32
acl to_localhost dst 127.0.0.0/8 0.0.0.0/32


acl our_sites dstdomain mysite.com
http_access allow our_sites
cache_peer_access myAccel allow our_sites
cache_peer_access myAccel deny all
  • change the second line with your ip (or leave localhost) and the port you are using to test. This is the address of your application.
  • You can optionally change the 3128 port.
  • run from command line sbin\squid –z . This will create the cache structure on disk.
  • run squid.

Testing against Squid

Now, if you invoke a request on the same uri (but using the squid port), several times from Fiddler as follows:

#REQUEST

GET http://localhost:3128/order/294912 HTTP/1.1
User-Agent: Fiddler
Accept: text/xml
Host: localhost:3128

The application server is not touched for all request to the reverse proxy. Only after 10 seconds we receive a conditional get and most of the time we will answer that request very quickly, i.e. without going to the database. You can put a breakpoint in the delegate channel and you will see no activity.

Then if you go to the access_log.txt of squid, you will see this:

1303947187.453    720 127.0.0.1 TCP_REFRESH_MISS/200 1197 GET http://mysite.com:3128/order/294912 - FIRST_UP_PARENT/myAccel text/xml
1303947189.907      0 127.0.0.1 TCP_MEM_HIT/200 1204 GET http://mysite.com:3128/order/294912 - NONE/- text/xml
1303947190.501      0 127.0.0.1 TCP_MEM_HIT/200 1204 GET http://mysite.com:3128/order/294912 - NONE/- text/xml
1303947191.031      0 127.0.0.1 TCP_MEM_HIT/200 1204 GET http://mysite.com:3128/order/294912 - NONE/- text/xml
1303947191.251      0 127.0.0.1 TCP_MEM_HIT/200 1204 GET http://mysite.com:3128/order/294912 - NONE/- text/xml
1303947191.451      0 127.0.0.1 TCP_MEM_HIT/200 1204 GET http://mysite.com:3128/order/294912 - NONE/- text/xml
1303947191.641      0 127.0.0.1 TCP_MEM_HIT/200 1204 GET http://mysite.com:3128/order/294912 - NONE/- text/xml
1303947191.977      0 127.0.0.1 TCP_MEM_HIT/200 1204 GET http://mysite.com:3128/order/294912 - NONE/- text/xml
1303947192.037      0 127.0.0.1 TCP_MEM_HIT/200 1204 GET http://mysite.com:3128/order/294912 - NONE/- text/xml
1303947216.296   1901 127.0.0.1 TCP_REFRESH_MISS/200 1197 GET http://mysite.com:3128/order/294912 - FIRST_UP_PARENT/myAccel text/xml
1303947219.461      0 127.0.0.1 TCP_MEM_HIT/200 1204 GET http://mysite.com:3128/order/294912 - NONE/- text/xml
1303947220.997      0 127.0.0.1 TCP_MEM_HIT/200 1204 GET http://mysite.com:3128/order/294912 - NONE/- text/xml

where TCP_MEM_HIT means "A valid copy of the object was in the memory cache", while "TCP_REFRESH_MISS" means the requested object wasn't in the cache.

Final notes

This is the way the web scale. Now a client can be polling and our application without bother our application.

If you want to learn more about caches, http and rest; I strongly recommend you the book Rest In Practice.
This is part of a major example application I am doing in Tellago. The sample application will be Open Source and released soon.

I hope you find this useful, or at least… informative.

| More

I wrote an approach to make -resource linking- easier with the new Web Api in this post. This is an alternative approach and I think it is much better.

This time I wrote the Uri template in only one place;

[ServiceContract, WithUriPrefix("products")]
public class ProductsResourceHandler
{
    [WebGet(UriTemplate = "")]
    public Product[]  Get()
    {
        //handle 
    }
    
    [WebGet(UriTemplate = "{productId}")]
    public Product GetProductById(int productId)
    {
        //handle 
    }
}

Now, if I with my uri template there; I can register all routes as follows:

public static class RouteTableConfigurator
{
    public static void Configure(IHttpHostConfigurationBuilder builder)
    {
        var routeInfo = typeof (RouteTableConfigurator)
            .Assembly.GetTypes()
            .Where(t => Attribute.IsDefined(t, typeof (ServiceContractAttribute))
                        && Attribute.IsDefined(t, typeof (WithUriPrefix)))
            .Select(t => new{ ServiceType = t, UriPrefix = GetPrefix(t)});

        var routes = routeInfo
            .Select(rinfo => new ServiceRoute(rinfo.UriPrefix, 
                                              new HttpConfigurableServiceHostFactory
                                                    {
                                                        Builder = builder
                                                    }, 
                                              rinfo.ServiceType));


        foreach (var route in routes)
        {
            RouteTable.Routes.Add(route);
        }
    }

    private static string GetPrefix(Type t)
    {
        return t.GetCustomAttributes(typeof(WithUriPrefix), true)
                .OfType<WithUriPrefix>()
                .First().Uri;
    }
}

This only works if you can register everything with the same configuration, otherwise you will must to define other set of conventions. But for this example it works

Then my IResourceLinker interface is:

public interface IResourceLinker
{
    string GetUri<T>(Expression<Action<T>> method, object uriArgs = null);
}

How the implementation should work?

[TestFixture]
public class LocationsSpecifications
{
    
    protected IResourceLinker resourceLinker 
        = new ResourceLinker("http://foo.bar");
    
    [Test]
    public void TheUriOfProductsIsOk()
    {
        resourceLinker.GetUri<ProductsResourceHandler>(pr => pr.Get())
            .Should().Be.EqualTo("http://foo.bar/products");
    }

    [Test]
    public void TheUriToGetAProductIsOk()
    {
        resourceLinker.GetUri<ProductsResourceHandler>(pr => pr.GetProductById(0), 
                                                       new{productId = 123})
            .Should().Be.EqualTo("http://foo.bar/products/123");
    }
}

And the implementation is:

public class ResourceLinker : IResourceLinker
{
    private readonly Uri baseUri;

    public ResourceLinker(string baseUri)
    {
        this.baseUri = new Uri(baseUri, UriKind.Absolute);
    }

    public string GetUri<T>(Expression<Action<T>> method, object uriArgs = null)
    {
        string prefix = GetServicePrefix<T>();

        var methodInfo = ((MethodCallExpression)method.Body).Method;
        var methodTemplate = GetUriTemplateForMethod(methodInfo);
    
        var newBaseUri = new Uri(baseUri, prefix);
        var uriTemplate = new UriTemplate(methodTemplate, true);

        return uriTemplate.BindByName(newBaseUri, ToDictionary(uriArgs ?? new{})).ToString();
    }

    public static IDictionary<string, string> ToDictionary(object anonymousInstance)
    {
        var dictionary = anonymousInstance as IDictionary<string, string>;
        if (dictionary != null) return dictionary;

        return TypeDescriptor.GetProperties(anonymousInstance)
            .OfType<PropertyDescriptor>()
            .ToDictionary(p => p.Name, p => p.GetValue(anonymousInstance).ToString());
    }

    private static string GetServicePrefix<T>()
    {
        var withUriPrefixAttribute = typeof (T)
                            .GetCustomAttributes(typeof (WithUriPrefix), true)
                            .OfType<WithUriPrefix>()
                            .FirstOrDefault();

        if(withUriPrefixAttribute == null )
        {
            var message = string.Format("Can't find the WithUriPrefix in {0}", typeof(T).Name);
            throw new InvalidOperationException(message);
        }
        return withUriPrefixAttribute.Uri;
    }

    private static string GetUriTemplateForMethod(MethodInfo method)
    {
        var webGet = method.GetCustomAttributes(true)
                            .OfType<WebGetAttribute>()
                            .FirstOrDefault();
        if (webGet != null) return webGet.UriTemplate ?? method.Name;

        var webInvoke = method.GetCustomAttributes(true)
                            .OfType<WebInvokeAttribute>()
                            .FirstOrDefault();
        if (webInvoke != null) return webInvoke.UriTemplate ?? method.Name;

        var message = string.Format("The method {0} is not a web method.", method.Name);
        throw new InvalidOperationException(message);
    }
}

I am still not happy with this, but it is nicer and less invasive than the first aproach.

| More

I just saw a chunk of code in Ayende's blog as follows:

public class HomeController : SessionController
{
    public ActionResult Blog(int id)
    {
        var blog = Session.Get<Blog>(id);

        return Json(new
        {
            blog.AllowsComments,
            blog.CreatedAt,
            blog.Id,
            blog.Subtitle
        }, JsonRequestBehavior.AllowGet);
    }
}

I like using anonymous types in this fashion and then tests as follows:

dynamic result = ((JsonResult)controller.Blog(1)).Data;

Assert.AreEqual("The subtitle", result.Subtitle);
Assert.AreEqual(1, result.Id);

If you do so, it is not going to work...Why? The quick answer is that anonymous type are internal.

The solution is very simple, edit the AssemblyInfo.cs in the project of the controllers and add the following code:

[assembly: InternalsVisibleTo("MySuperProject.Tests")]

Replace the "MySuperProject.Tests" with the name of your test project.

| More

I am doing some experiments with the Nancy and let me say that it looks pretty neat so far. This is an experiment about content negotiation.

Content negotiation is defined in wikipedia as:

Content negotiation is a mechanism defined in the HTTP specification that makes it possible to serve different versions of a document (or more generally, a resource) at the same URI, so that user agents can specify which version fit their capabilities the best.

This is something that will be supported in Nancy in future versions automatically. And even you will be able to override the behavior.

So far you can do something like:

public class SampleModule : NancyModule
{
    public SampleModule()
    {
        Get["example", c => c.Request.Accept("application/xml")] =
            a => Response.AsXml("hello xml");

        Get["example", c => c.Request.Accept("application/json")] =
            a => Response.AsJson("hello json");
    }
}

The Accept method is an extension method as follows:

public static class RequestHelper
{
    public static bool Accept(this Request request, string contentType)
    {
        return request.Headers.ContainsKey("Accept") 
            && request.Headers["Accept"]
                        .Any(c => c.Contains(contentType));
    }
}

This might seem an overhead for simple cases like Xml/Json but it opens the door for cases like rest versioning. I took this example from my friend (and now coworker) Pablo Cibraro.

For this example we have two different media types:

public static class MediaTypes
{
  public const string Version1 
        = "application/vnd.mycompany.myapp+xml";

  public const string Version2 
        = "application/vnd.mycompany.myapp-v2+xml";
}

And then we need to respond with two different representations of our Customer resource for each media type. One of them has address and the other one doesnt:

public class SampleModule : NancyModule
{
    public SampleModule()
    {
        Get["customer/{id}", c => c.Request.Accept(MediaTypes.Version1)] =
            a => Response.AsXml(new Customer{ Name = "Sideshow Bob" });

        Get["customer/{id}", c => c.Request.Accept(MediaTypes.Version2)] =
            a => Response.AsJson(new CustomerV2
                                      { 
                                        Name = "Sideshow Bob" 
                                        Addresses = { {"State Prison"} }
                                      });
    }
}

This show some of the power of Nancy:

  • The delegate to select the handler is separated from the handler itself.
  • Two handler for the same routes.

You can refactor this in two separated methods.

In contrasts the new WCF Web Apis (current version of Jan-2011) has a very useful processors pipelines but you have to handle the Route + VERB in the same method.

| More

In this post I will map the same domain I used in the previous post about EntityFramework but without the overhead of the crazy properties I had to add to fix the deficiencies of EntityFramework 4.1:

2011-03-29_2015_001

For this post I’m using the following nugets:

  • ConfORM (depends on NHibernate): This help me to automap the domain to a relational model based on conventions.
  • NHibernate.LinFu: This is a proxy generator used by nhibernate for lazy loading. Note that the next version of NHibernate 3.2 (trunk) doesn’t need this. It is inside NHibernate.dll
  • NHibernate.SetForNet4: This is because NHibernate doesn’t support System.Collections.Generic.ISet<T> out of the box. ISet<T> is from .Net 4, while nhibernate support set mapping from version 1 with Iesi.Collections. This nuget add support for lazy loading an ISet<T>

This is a console project and I have the following files:

2011-03-31_1047

Net4Collections is a class installed by the NHibernate.SetForNet4, so the only I did for this example was:

internal class Program
{
    private static void Main()
    {
        HbmMapping mappings = AutomapDomain(typeof (Order),
                                            typeof (OrderItem),
                                            typeof (Product),
                                            typeof (Customization));

        Configuration configuration = ConfigureNHibernate(mappings);
        Console.WriteLine("Generating the schema");
        new SchemaExport(configuration).Create(true, true);

        Console.WriteLine("Persiting some objects");
        var sf = configuration.BuildSessionFactory();
        
        using(var s = sf.OpenSession())
        using(var tx = s.BeginTransaction())
        {
            s.Save(new Product
                       {
                           Name = "Fideos",
                           Customizations = {new Customization
                                                 {
                                                     Name = "Tuco",
                                                     PossibleValues = {"Pocon", "Medio", "Sopa"}
                                                 }}
                       });
            tx.Commit();
        }
        Console.ReadLine();
    }

    private static HbmMapping AutomapDomain(params Type[] entities)
    {
        var orm = new ObjectRelationalMapper();
        //We are telling here to conform that ISet<> properties should be mapped as <set>
        orm.Patterns.Sets.Add(
            m => m.GetPropertyOrFieldType()
                  .GetGenericIntercafesTypeDefinitions()
                  .Contains(typeof (ISet<>)));

        orm.TablePerClass(entities);
        CustomizeMappings(orm);

        //Some ConfORM.Shop patterns
        var englishInflector = new EnglishInflector();
        var patterns = new SafePropertyAccessorPack()
            .Merge(new CoolTablesAndColumnsNamingPack(orm))
            .Merge(new PluralizedTablesPack(orm, englishInflector)
            .Merge(new CollectionOfElementsColumnApplier(orm, englishInflector)));

        //Mapper
        var mapper = new Mapper(orm, patterns);

        var mapping = mapper.CompileMappingFor(entities);
        Console.WriteLine(Serialize(mapping));
        return mapping;

    }

    private static void CustomizeMappings(ObjectRelationalMapper orm)
    {
        orm.PersistentProperty<Order>(o => o.Total);
        orm.Cascade<Product, Customization>(Cascade.All);
    }

    private static Configuration ConfigureNHibernate(HbmMapping mapping)
    {
        var configuration = new Configuration();

        //nhibernate support for ISet<>
        configuration.CollectionTypeFactory<Net4CollectionTypeFactory>();

        //Use linfu proxy facotory: NOTE: This is going to be deprecated in vNext.
        configuration.Proxy(p => p.ProxyFactoryFactory<ProxyFactoryFactory>());

        //The database connection configuration
        configuration.DataBaseIntegration(db =>
                                              {
                                                  db.KeywordsAutoImport = Hbm2DDLKeyWords.AutoQuote;
                                                  db.Dialect<MsSql2008Dialect>();
                                                  db.Driver<SqlClientDriver>();
                                                  db.ConnectionStringName = "NHibernateTest";
                                                  db.LogSqlInConsole = true;
                                                  db.LogFormatedSql = true;
                                              });


        configuration.AddDeserializedMapping(mapping, "AllMappings");

        return configuration;
    }

    //This method is only used to show you in the console the nhibernate mappings in XML 
    protected static string Serialize(HbmMapping hbmElement)
    {
        var setting = new XmlWriterSettings {Indent = true};
        var serializer = new XmlSerializer(typeof (HbmMapping));
        using (var memStream = new MemoryStream())
        using (XmlWriter xmlWriter = XmlWriter.Create(memStream, setting))
        {
            serializer.Serialize(xmlWriter, hbmElement);
            memStream.Flush();
            memStream.Position = 0;

            var sr = new StreamReader(memStream);
            return sr.ReadToEnd();
        }
    }
}

There are only one customization in this example to map the readonly property. By default ConfORM doesn’t map readonly properties but as I said yesterday I was trying to do so in EntityFramework…
I am using a set of conventions to map the domain, the power of ConfORM to infer most of the things and also ConfORM.Shop.dll that comes with the ConfORM nuget package to generate this beautiful schema:

2011-03-31_1115

Please take your time to examine this schema.

Want to see the output of the console?

Generating the schema

    if exists (select 1 from sys.objects where object_id = OBJECT_ID(N'[FK3E8588581FEFE3AB]') AND parent_object_id = OBJECT_ID('OrderItems'))
alter table OrderItems  drop constraint FK3E8588581FEFE3AB


    if exists (select 1 from sys.objects where object_id = OBJECT_ID(N'[FK3E858858F373BEAE]') AND parent_object_id = OBJECT_ID('OrderItems'))
alter table OrderItems  drop constraint FK3E858858F373BEAE


    if exists (select 1 from sys.objects where object_id = OBJECT_ID(N'[FKEF9298D4286FF938]') AND parent_object_id = OBJECT_ID('OrderItemPreferences'))
alter table OrderItemPreferences  drop constraint FKEF9298D4286FF938


    if exists (select 1 from sys.objects where object_id = OBJECT_ID(N'[FKC2F496971FEFE3AB]') AND parent_object_id = OBJECT_ID('Customizations'))
alter table Customizations  drop constraint FKC2F496971FEFE3AB


    if exists (select 1 from sys.objects where object_id = OBJECT_ID(N'[FK956AE80DAF824711]') AND parent_object_id = OBJECT_ID('CustomizationPossibleValues'))
alter table CustomizationPossibleValues  drop constraint FK956AE80DAF824711


    if exists (select * from dbo.sysobjects where id = object_id(N'Orders') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table Orders

    if exists (select * from dbo.sysobjects where id = object_id(N'OrderItems') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table OrderItems

    if exists (select * from dbo.sysobjects where id = object_id(N'OrderItemPreferences') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table OrderItemPreferences

    if exists (select * from dbo.sysobjects where id = object_id(N'Products') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table Products

    if exists (select * from dbo.sysobjects where id = object_id(N'Customizations') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table Customizations

    if exists (select * from dbo.sysobjects where id = object_id(N'CustomizationPossibleValues') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table CustomizationPossibleValues

    if exists (select * from dbo.sysobjects where id = object_id(N'hibernate_unique_key') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table hibernate_unique_key

    create table Orders (
        Id BIGINT not null,
       [Date] DATETIME null,
       Status INT null,
       Location INT null,
       primary key (Id)
    )

    create table OrderItems (
        Id BIGINT not null,
       ProductId BIGINT null,
       Quantity INT null,
       UnitPrice DECIMAL(19,5) null,
       OrderId BIGINT null,
       primary key (Id)
    )

    create table OrderItemPreferences (
        OrderItemId BIGINT not null,
       Preference NVARCHAR(255) null,
       idx NVARCHAR(255) not null,
       primary key (OrderItemId, idx)
    )

    create table Products (
        Id BIGINT not null,
       Name NVARCHAR(255) null,
       Price DECIMAL(19,5) null,
       primary key (Id)
    )

    create table Customizations (
        Id BIGINT not null,
       Name NVARCHAR(255) null,
       ProductId BIGINT null,
       primary key (Id)
    )

    create table CustomizationPossibleValues (
        CustomizationId BIGINT not null,
       PossibleValue NVARCHAR(255) null
    )

    alter table OrderItems 
        add constraint FK3E8588581FEFE3AB 
        foreign key (ProductId) 
        references Products

    alter table OrderItems 
        add constraint FK3E858858F373BEAE 
        foreign key (OrderId) 
        references Orders

    alter table OrderItemPreferences 
        add constraint FKEF9298D4286FF938 
        foreign key (OrderItemId) 
        references OrderItems

    alter table Customizations 
        add constraint FKC2F496971FEFE3AB 
        foreign key (ProductId) 
        references Products

    alter table CustomizationPossibleValues 
        add constraint FK956AE80DAF824711 
        foreign key (CustomizationId) 
        references Customizations

    create table hibernate_unique_key (
         next_hi BIGINT 
    )

    insert into hibernate_unique_key values ( 1 )
Persiting some objects
NHibernate: 
    select
        next_hi 
    from
        hibernate_unique_key with (updlock,
        rowlock)
NHibernate: 
    update
        hibernate_unique_key 
    set
        next_hi = @p0 
    where
        next_hi = @p1;
    @p0 = 2 [Type: Int64 (0)], @p1 = 1 [Type: Int64 (0)]
NHibernate: 
    select
        next_hi 
    from
        hibernate_unique_key with (updlock,
        rowlock)
NHibernate: 
    update
        hibernate_unique_key 
    set
        next_hi = @p0 
    where
        next_hi = @p1;
    @p0 = 3 [Type: Int64 (0)], @p1 = 2 [Type: Int64 (0)]
NHibernate: 
    INSERT 
    INTO
        Products
        (Name, Price, Id) 
    VALUES
        (@p0, @p1, @p2);
    @p0 = 'Fideos' [Type: String (4000)], @p1 = 0 [Type: Decimal (0)], @p2 = 32768 [Type: Int64 (0)]
NHibernate: 
    INSERT 
    INTO
        Customizations
        (Name, Id) 
    VALUES
        (@p0, @p1);
    @p0 = 'Tuco' [Type: String (4000)], @p1 = 65536 [Type: Int64 (0)]
NHibernate: 
    UPDATE
        Customizations 
    SET
        ProductId = @p0 
    WHERE
        Id = @p1;
    @p0 = 32768 [Type: Int64 (0)], @p1 = 65536 [Type: Int64 (0)]
NHibernate: 
    INSERT 
    INTO
        CustomizationPossibleValues
        (CustomizationId, PossibleValue) 
    VALUES
        (@p0, @p1);
    @p0 = 65536 [Type: Int64 (0)], @p1 = 'Pocon' [Type: String (4000)]
NHibernate: 
    INSERT 
    INTO
        CustomizationPossibleValues
        (CustomizationId, PossibleValue) 
    VALUES
        (@p0, @p1);
    @p0 = 65536 [Type: Int64 (0)], @p1 = 'Medio' [Type: String (4000)]
NHibernate: 
    INSERT 
    INTO
        CustomizationPossibleValues
        (CustomizationId, PossibleValue) 
    VALUES
        (@p0, @p1);
    @p0 = 65536 [Type: Int64 (0)], @p1 = 'Sopa' [Type: String (4000)]

In this domain we have things like ISet and IDictionary (the OrderItemPreferences table).
It is a quite simple example but as you can see ConfORM resolve most of the things *automagicallly although you can customize everything.

There is also an inflector for Spanish and Italian in ConfORM.Shop. You don’t need an inflector to work with ConfORM you can remove all that part and use singular names.

I'll publish this example somewhere soon. But if you need to get into ConfORM I strongly recommend you to see the ConfOrm.UsageExamples and also NHibernate.Mystic.

I did a lot of corrections to this article after published; thank Fabio Maulo very much for doing a deep review.

| More

This is my experience with EF 4.1 Code First so far. It may be useful for you given my background in NHibernate.

I am not trying to start a rant against it. Just to highlight the state of the art; and how you might overcome to some problems.

The domain I tried to map was this:

2011-03-29_2015

Four classes, Two enums.

I just want to keep this clear; I will talk about very simple cases. I know that I can handle really really convoluted scenarios with NHibernate as ORM but I will talk about the most common scenarios I have seen.

Swallowing exceptions

This is one of the most irritating things. I’ve seen two cases for this so far:

  • If you don’t set a connection string or your connection string name is wrong. EntityFramework doesn’t throw. Instead it creates a new database in the sqlexpress instance; named with the full namespace of the DbContext. Accessing with trusted connection of course. I’d expect rather something like this:

2011-03-29_2026

  • If you have sealed properties; everything will work. It is even going to save an object with a many-to-one relationship with the right values in the database and it will load the object back. Surprisingly the reference will be null instead of a proxy (this is obviously for lazy loading stuff). NHibernate will throw by default an exception given you a list of the sealed methods;

2011-03-29_2034

Of course you can disable this to speed up the built of the session factory but that is pointless because it is supposed to happen once.

In my humble opinion they should have more care with those things if you don’t want to annoy developers with odd results.

Possible workaround

There is not; this is EF internals. If you don’t want to deal with “virtual” thing and make everything virtual you should definitely take a look to Virtuosity; a project from my friend Simon.

Logging facilities

There is no way to have a look what commands are going to the database. This is widely used in the NHibernate world and you have two ways by simply using show_sql = true or using a logging framework like log4net.

Possible workaround

There are some hacks; like wrapping the database connection provider; as explained here but it didn’t work for me. The other thing you can do is to use EfProf, this is a commercial product and serve for a wide range of purposes.

Lack of good identifiers generators

EntityFramework support two kind of Persistent Object ID generation techniques; identity and assigned.  NHibernate 2.1 have 17 techniques for generating your POID (article from 2009) and  the two most discouraged patterns are; identity and assigned. This is not a minor thing for an ORM:

Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems.

At some point this means that you will be sending the operations as a batch when flushing. But “identity” in sql server is a bad strategy because you don’t know the ID before inserting the record; you need to insert the record and then you can ask for the ID (or the last id). Even Sequences (in most of the DBMS) work better because you can pull numbers without inserting anything.

Keep in mind that EntityFramework work quite different than NHibernate regarding this:

  • NHibernate ensure than the Save method (before flushing to the database) will put an ID in the entity, so you can operate with the entity ID before flushing the changes. This is very important when you use a pattern like session-per-request; because you will probably use the ID for something else like generating a link.
  • EntityFramework ensure the unit of work works as unit and will not give you the ID before flushing the changes.

What is the best? I am not sure because identity is a very bad thing despite how you use it. It is not an ORM problem is just bad and any DBA will agree on this.

Posible workarounds

This is easy to fix in the current status of EntityFramework. Don’t use identity:

modelBuilder.Conventions.Remove<StoreGeneratedIdentityKeyConvention>();

and EntityFramework will think that you are going to use assigned. From here you have two paths:

  • If you don’t want to generate human-readable values; stick to GUID and use something like this in the constructor of the entity:
public EntityBase
{
  public EntityBase()
  {
     Id = Guid.NewGuid()
  }
  public Guid Id { get; set; }
}

We are generating a Guid in the constructor; every entity will have an Id before flushing and… when you load an entity EF will put the right id (that comes from the database) in the ID property after constructing the instance.

  • If you want to generate human-readable values; I encourage you to use the HiLo algorithm. Fortunately I write a post some days ago. I been working in this and I’ve enhanced the design of that classes but I will not publish yet until I get something more mature.

Lack of customizable mapping types

NHibernate has a really important extension point; the interface IUserType. I use at least one custom implementation in every project. What does this interface? Is pretty simpler; It allows you to describe how a value will be read and write to/from the database.

Let’s say that you are working on legacy database and it uses “N” and “S” (from Spanish “si” = “yes”). You can map this to a char property on .Net but it is not right because the true meaning of this in the c# language would be “System.Boolean”. So NHiberante allows you to decouple the database implementation from the object oriented implementation.

The same thing is used for mapping enums to the database. NHibernate comes with a handy collection of useful user types.

There is another interface named ICompositeUserType that allows to map a property to multiple columns in the database; it is not widely used/known though.

Possible workarounds

It is ugly, but for mapping enums I did something like this:

#region EntityFramework Specific
[Obsolete("EntityFramework can't map enums.")]
public virtual string StatusString
{
    get { return Status.ToString(); }
    set
    {
        OrderStatus newValue;
        if (Enum.TryParse(value, out newValue))
        {
            Status = newValue;
        }
    }
}
#endregion

public virtual OrderStatus Status { get; set; }

Lack of Read-Only properties

ReadOnly properties in NHibernate means than the value is going to be saved and updated in the database but it will never be read from the database because it is a read-only property:

public decimal Total
{
  get{
    Items.Sum(i => i.Quantity * i.Price);
  }
}

There is a full explanation here, from my friend Germán Schuager.
This most of the time means a de-normalization of the database; but it is quite right because you will be saving the total of an invoice almost always for sure.

Possible workaround

Carlos Peix illuminated me in twitter:

2011-03-29_2132

Yes! Carlos you were right:

public decimal Total
{
  get{
    Items.Sum(i => i.Quantity * i.Price);
  }
  set{ 
     // no op 
  }
}

we can fool EntityFramework this way.

Lack of collection of Elements

This means that EntityFramework doesn’t currently support ISet<string>, ICollection<string> or ISet<int> as property. NHibernate support this from earlier versions. It will simply use another table for storing the elements. You can have even collection of enums because it will use the same mechanism for every type; a plain IUserType as explained above.

NHibernate also support collection of components; entities without meaning outside like Address or telephone.

Possible workaround

I’ve used for the above domain some kind of de-normalization and serialization/parsing;

[Obsolete("EntityFramework doesn't store collection of elements.")]
public virtual string CommaSepparatedPossibleValues
{
    get { return string.Join(",", possibleValues); }
    set
    {
        if(value == null) return;
        value.Split(',')
             .ToList()
             .ForEach(v => possibleValues.Add(v));
    }
}

Lack of MAP mapping or Dictionary mapping

The term “map” come from the java world; while in .Net map means exactly Dictionary. NHibernate can handle a widely variety of dictionaries:

  • Element as Key, Element as Value
  • Element as Key, Component as Value
  • Element as Key, Entity (many-to-many) as value
  • Component as Key, Element as Value
  • Component as Key, Component as Value
  • Component as Key, Entity (many-to-many) as value
  • Entity (many-to-many) as Key, Element as value
  • Entity (many-to-many) as Key, Component as value
  • Entity (many-to-many) as Key, Entity as value

This is very well explained here. 

Possible workaround

There isn’t. The domain has only one case of IDictionary<string, string>. I handle with something very similar to the previous workaround.

The cost of the workarounds

Most of these workarounds come with a price.

  • You will not be able to query in those properties by sure.
  • You will pollute your entities with weird properties, like an empty set (in a read-only property) or two properties for converting something.

Non-technical issues

Lack of documentation

There is a bad combination between long release cycles with a product that is pushed by a big company and has lot of people around writing articles on alphas, betas and so on. If you do a google search for something you will find a variety of API that are not currently supported. You can try this right now do a search for:

  • disable identity generator
  • generating the database schema
  • mapping a many to many

I can’t really understand why people say than this is a pro on EntityFramework right now. Even the MSDN documentation doesn’t match the current programming API.

On the other hand NHibernate has a good reference documentation and lot of posts with working examples. In fact; when lurking for a problem sometimes I found the answer in the hibernate reference documentation or even in the hibernate forums!. Is NHibernate exempt of this kind of problem? definitely no for instance NHibernate has a vocabulary that doesn’t always match with the FluentNHibernate ones; mutable=”false” in nhibernate is “ReadOnly()” in FNH. But is pretty common from bloggers to mark something as outdated. Another example is that for instance even if we have like 5 official different ways of mapping a class if you ask a question in the forum you know that you should send the official dialect: plain old xml (aka POX).

Ignoring the progress of the OpenSource community

The NHibernate/Hibernate community has decades dealing with this. Ignore them it is not the best thing.
I thought Microsoft had overcome to this;

  • Mef was one of the first in codeplex
  • Asp.Net MVC is OSS
  • The new WCF web api is OSS
  • NuGet is the new guy on the block

While EF team is trying to figure out how to create a good fluent API; NHibernate has a production-ready API since long time that work for a lot of projects ( FluentNHibernate ). It has two attribute based APIS NHibernate.Mapping.Attributes and Castle.ActiveRecord. It has a convention based API more powerful than the one it comes out of the box with EF; -because you can actually define conventions- ( FluentNHibernate AutoMappings ). And now it has a another convention based API that can read your mind; it has set of powerful conventions for inferring your mappings via reflection and a powerful set of conventions to make your DBA happy ( ConfORM ).

So, my two cents on this; is to keep an eye in the community. There are lot of clever people willing to help.

I hope you find this article interesting if you are coming from NH to EF or if you are still in NH to get an idea how are going things in EF.

If you find something wrong in one of the points made here; don’t hesitate to send me a comment, tweet, mail or whatever.

| More

I wrote a little implementation of the HiLo pattern for EntityFramework. Those who are using NHibernate currently already knows how this pattern works but I am going to give a little explanation.

The Hi/Lo pattern describe a mechanism for generating safe-ids on the client side rather than the database. Safe in this context means without collisions. This pattern is interesting for three reasons:

  • It doesn’t break the Unit of Work pattern (check  this link and this other one)
  • It doesn’t need many round-trips as the Sequence generator in other DBMS.
  • It generates human readable identifier unlike to GUID techniques.

How it works?

The identifier generated is composed of two parts; the Hi part and the Lo part. The Hi part of the identifier is controlled by the database while the Lo part is controlled by the client side. Applications need to agree in only one parameter called “MaxLo”.

Imagine we agree to use a MaxLo of 100. Once the application needs to generate an ID for the first time; it will ask a Hi to the database; suppose the database returns “1”.  Now the application knows, that it can use identifiers from 1 to 100. Once the application run out of “Lo” because it hits the MaxLo; the application will ask for another Lo to the database.

NHibernate support this out of the box while EntityFramework is far from that.

Test case

I didn’t write much tests cases for this feature but this should be very descriptive:

[Test]
public void ShouldWork()
{
    var expected = Enumerable.Range(0, 200).Select(i => (long)i).ToList();

    using(var context = new SampleContext())
    {
        //create 200 products:
        var products = Enumerable.Range(0, 200)
            .Select(i => new Product {Name = string.Format("Test product {0}", i) }).ToList();
        
        //add to the dbSet: DO NOT FLUSH THE CHANGES YET.
        products.ForEach(p => context.Orders.Add(p));
        
        //Assert
        products.Select(p => p.Id)
            .Should().Have.SameSequenceAs(expected);


        context.SaveChanges();
    }
}

First; create 200 new products; then call the method Add of the DbSet. One of the interesting things about this, is that I want the ID right when I call Add, despite if I flush the changes or no.

Solution

The first class is the HiLoGenerator:

public class HiLoGenerator<TDbContext> : IHiLoGenerator
    where TDbContext : DbContext, new()
{
    private static readonly object ConcurrencyLock = new object();
    private readonly int maxLo;
    private string connectionString;
    private long currentHi = -1;
    private int currentLo;

    public HiLoGenerator(int maxLo)
    {
        this.maxLo = maxLo;
    }

    #region IHiLoGenerator Members

    public long GetIdentifier()
    {
        long result;
        lock (ConcurrencyLock)
        {
            if (currentHi == -1)
            {
                MoveNextHi();
            }
            if (currentLo == maxLo)
            {
                currentLo = 0;
                MoveNextHi();
            }
            result = (currentHi*maxLo) + currentLo;
            currentLo++;
        }
        return result;
    }

    public void SetConnectionString(string newConnectionString)
    {
        connectionString = newConnectionString;
    }

    #endregion

    private void MoveNextHi()
    {
        using (var connection = CreateConnection())
        {
            connection.Open();
            using (var tx = connection.BeginTransaction(IsolationLevel.Serializable))
            using (var selectCommand = connection.CreateCommand())
            {
                selectCommand.Transaction = tx;
                selectCommand.CommandText =
                    "SELECT next_hi FROM entityframework_unique_key;" +
                     "UPDATE entityframework_unique_key SET next_hi = next_hi + 1;";
                currentHi = (int)selectCommand.ExecuteScalar();

                tx.Commit();
            }
            connection.Close();
        }
        
    }

    private IDbConnection CreateConnection()
    {
        using (var dbContext = new TDbContext())
        {
            var connectionType = dbContext.Database.Connection.GetType();
            connectionString = connectionString ?? dbContext.Database.Connection.ConnectionString;
            return (IDbConnection) Activator.CreateInstance(connectionType, connectionString);
        }
    }
}

This class is intented to be used as singleton; for the whole application. That’s why it has a concurrency look. The most important thing happens here:

result = (currentHi * maxLo) + currentLo;

Then we need to tweak our DbContext as follows:

public class SampleContext : DbContext
{
    private static readonly HiLoGenerator<SampleContext> HiloGenerator 
        = new HiLoGenerator<SampleContext>(100);

    private IDbSet<Product> orders;
    public IDbSet<Product> Orders
    {
        get { return orders; }
        set { orders = new HiLoSet<Product>(value, HiloGenerator); }
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<StoreGeneratedIdentityKeyConvention>();
        modelBuilder.Entity<Product>().HasKey(p => p.Id);
    }
}

And then the HiLoSet is a wrapper arround DbSet;

public class HiLoSet<T> : IDbSet<T> where T : EntityBase
{
    private readonly IDbSet<T> dbSet;
    private readonly IHiLoGenerator generator;

    public HiLoSet(IDbSet<T> dbSet, IHiLoGenerator generator)
    {
        this.dbSet = dbSet;
        this.generator = generator;
    }

    public T Add(T entity)
    {
        var add = dbSet.Add(entity);
        TrySetId(entity);
        return add;
    }

    private void TrySetId(EntityBase entity)
    {
        if (entity.Id == default(long))
        {
            entity.Id = generator.GetIdentifier();
            HandleChildsObjects(entity);
        }
    }

    private void HandleChildsObjects(EntityBase entity)
    {
        var propertyInfos = new List<PropertyInfo>();
        var typeToLook = entity.GetType();
        do
        {
            var newProps = entity.GetType()
                .GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .Where(p => typeof(IEnumerable<EntityBase>).IsAssignableFrom(p.PropertyType)).ToList();
            propertyInfos.AddRange(newProps);
            typeToLook = typeToLook.BaseType;
        } while (typeToLook != typeof (object));
        

        var aggregated = propertyInfos
            .Select(p => p.GetValue(entity, null))
            .OfType<IEnumerable<EntityBase>>()
            .Where(col => col != null).SelectMany(col => col);
        foreach (var child in aggregated)
        {
            TrySetId(child);
        }
    }

    #region no op methods
        public IEnumerator<T> GetEnumerator()
        {
            return dbSet.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IEnumerable)dbSet).GetEnumerator();
        }

        public Expression Expression
        {
            get { return dbSet.Expression; }
        }

        public Type ElementType
        {
            get { return dbSet.ElementType; }
        }

        public IQueryProvider Provider
        {
            get { return dbSet.Provider; }
        }

        public T Find(params object[] keyValues)
        {
            return dbSet.Find(keyValues);
        }

        public T Remove(T entity)
        {
            return dbSet.Remove(entity);
        }

        public T Attach(T entity)
        {
            return dbSet.Attach(entity);
        }

        public T Create()
        {
            return dbSet.Create();
        }

        public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T
        {
            return dbSet.Create<TDerivedEntity>();
        }

        public ObservableCollection<T> Local
        {
            get { return dbSet.Local; }
        }
        #endregion
}

When we call the Add method, we set the ids for the object and we even explore the child objects to do the same.
It is a hacky solution but will work for most of the cases.
That is all the code! I hope you find useful.

| More

I’ve been learning and experimenting a lot of WCF as part of my new job this week on Tellago.

Here is something that I did this week and I’ll like to share with my readers.

This post uses the WCF Web APIs Preview 3, releases on Jan 14 of 2011. The API might change in the near future.

One of the most important things about building Http-based REST services (wait! resources Guiño) is the location.

Let’s start with a pretty basic example (this is from ContactManager; the sample application at wcf.codeplex.com):

[ServiceContract]
[Export]
public class ContactsResource
{
    private readonly IContactRepository repository;

    [ImportingConstructor]
    public ContactsResource(IContactRepository repository)
    {
        this.repository = repository;
    }

    [WebGet(UriTemplate = "")]
    public List<Contact> Get()
    {
        return this.repository.GetAll();
    }

    [WebInvoke(UriTemplate = "", Method = "POST")]
    public Contact Post(Contact contact, HttpResponseMessage response)
    {
        this.repository.Post(contact);
        response.StatusCode = HttpStatusCode.Created;
        return contact;
    }
}

[ServiceContract]
[Export]
public class ContactResource
{
   private readonly IContactRepository repository;

   [ImportingConstructor]
   public ContactResource(IContactRepository repository)
   {
       this.repository = repository;
   }

   [WebGet(UriTemplate = "{id}")]
   public Contact Get(string id, HttpResponseMessage response)
   {
       var contact = this.repository.Get(int.Parse(id, CultureInfo.InvariantCulture));
       if (contact == null)
       {
           response.StatusCode = HttpStatusCode.NotFound;
           response.Content = new StringContent("Contact not found");
       }

       return contact;
   }

   [WebInvoke(UriTemplate = "{id}", Method = "PUT")]
   public Contact Put(string id, Contact contact, HttpResponseMessage response)
   {
       this.Get(id, response);
       this.repository.Update(contact);
       return contact;
   }

   [WebInvoke(UriTemplate = "{id}", Method = "DELETE")]
   public Contact Delete(string id)
   {
       var intId = int.Parse(id, CultureInfo.InvariantCulture);
       dynamic deleted = this.repository.Get(intId);
       this.repository.Delete(intId);
       return deleted;
   }
}

This article is focused in the method Post of the ContactsResource class.

The highlighted line set the status of the response to Created (Http Code = 202). In addition to that, I’d like to add to the header response the location indicating where this new “resource” is now.

We can do something like this:

response.StatusCode = HttpStatusCode.Created;
response.Header.Location = ..... + "contact/" +  contact.Id;

Where “contact” come from? Well, this is in the RouteTable, which is configured in the Global.asax.cs class as follows:

RouteTable.Routes.AddServiceRoute<ContactResource>("contact", configuration);
RouteTable.Routes.AddServiceRoute<ContactsResource>("contacts", configuration);

 

The problem

The problem with writing the route of the newly created resource in code as I did in the previous section, is not about “magic strings” or strongly-typeness; I can’t care less about magic strings because I am used to write tests. The main problem is:

  • Duplication; What is the uri template for this method? and How do I construct an Uri for this method?
  • I don’t know how is the URI template at this point without going to the method and looking at the attribute; then I’ve to go to the configuration of the routes table to see the prefix for the resource class.

The solution

I am going to use a little bit of reflection and the RouteTables to get the uri of the resource. I started with a some simple tests as follows:

[TestFixture]
public class ResourceLinkerTests
{
    public class SampleResource
    {
        [WebGet]
        public string GetSomething()
        {
            return string.Empty;
        }

        [WebGet(UriTemplate = "Zapato/{id}/{other}")]
        public string GetFoo(string id, 
                            string other, 
                            double somethingElseThanIsNotInTheRoute)
        {
            return string.Empty;
        }

        [WebInvoke]
        public void PostFoo() {}
        
        [WebInvoke(UriTemplate = "PostBar?lele={id}")]
        public void PostBar(int id) {}

        public void NotAWebMethod() {}
    }
    
    [SetUp]
    public void SetUp()
    {
        RouteTable.Routes.AddServiceRoute<SampleResource>("SuperResource", null);
    }
    
    [Test]
    public void CanGetRouteWithSimpleCase()
    {
        var uriResolver = new ResourceLinker("http://foo.bar");
        var result = uriResolver.GetUri<SampleResource>(sr => sr.GetSomething());
        result.ToString()
            .Should().Be.EqualTo("http://foo.bar/SuperResource/GetSomething");
    }


    [Test]
    public void CanGetValuatedUri()
    {
        var uriResolver = new ResourceLinker("http://foo.bar");
        var result = uriResolver.GetUri<SampleResource>(sr => sr.GetFoo("1", "2", 5467));
        result.ToString()
            .Should().Be.EqualTo("http://foo.bar/SuperResource/Zapato/1/2");
    }

    [Test]
    public void CanGetUriForWbeInvokeWithouAttribute()
    {
        var uriResolver = new ResourceLinker("http://foo.bar");
        var result = uriResolver.GetUri<SampleResource>(sr => sr.PostFoo());
        result.ToString()
            .Should().Be.EqualTo("http://foo.bar/SuperResource/PostFoo");
    }

    [Test]
    public void CanGetAnUriForWebInvokeWithUriTemplate()
    {
        var uriResolver = new ResourceLinker("http://foo.bar");
        var result = uriResolver.GetUri<SampleResource>(sr => sr.PostBar(123));
        result.ToString()
            .Should().Be.EqualTo("http://foo.bar/SuperResource/PostBar?lele=123");
    }

    [Test]
    public void WhenTheMethodIsNotAWebMethodThenThrow()
    {
        var uriResolver = new ResourceLinker("http://foo.bar");
        uriResolver.Executing(ur => ur.GetUri<SampleResource>(sr => sr.NotAWebMethod()))
                    .Throws();
    }

    [TearDown]
    public void TearDown()
    {
        RouteTable.Routes.Clear();
    }
}

As you might noticed, the SUT is the new class ResourceLinker. The SampleResource is a sample class that I use for testing the resolution of the URIs.

ResourceLinker has only one method named GetUri. I pass a lambda to the method ( Expression<Action<TResource>> ) with the parameters.

The GetFoo method has a parameter that is not included in the UriTemplate. This is really important because the Processor infrastructure of the WCF web api allows you to inject in these methods other things.

The first problem I faced was that calling AddServiceRoute within a unit test throws the following exception:

SetUp : System.InvalidOperationException : 'ServiceHostingEnvironment.EnsureServiceAvailable' cannot be invoked within the current hosting environment. This API requires that the calling application be hosted in IIS or WAS.

So, I made a wrapper around ServiceRoute as follows:

public interface IPrefixedRouteType
{
    Type ServiceType { get; }
    string RoutePrefix { get; }
}

public class LazyServiceRoute : RouteBase, IPrefixedRouteType
{
    private readonly string routePrefix;
    private readonly HttpHostConfiguration httpHostConfiguration;
    private readonly Type serviceType;
    private readonly Type webHttpServiceHostFactory;
    private readonly Lazy<ServiceRoute> lazyServiceRoute;

    public LazyServiceRoute(string routePrefix, 
                            HttpHostConfiguration httpHostConfiguration, 
                            Type serviceType)
        :this(routePrefix, httpHostConfiguration, serviceType, typeof(WebHttpServiceHostFactory))
    {}

    public LazyServiceRoute(string routePrefix, 
                            HttpHostConfiguration httpHostConfiguration, 
                            Type serviceType, 
                            Type webHttpServiceHostFactory)
    {
        this.routePrefix = routePrefix;
        this.httpHostConfiguration = httpHostConfiguration;
        this.serviceType = serviceType;
        this.webHttpServiceHostFactory = webHttpServiceHostFactory;
        lazyServiceRoute = new Lazy<ServiceRoute>(CreateServiceRoute);
    }

    private ServiceRoute CreateServiceRoute()
    {
        var hostFactory = (IConfigurableServiceHostFactory)Activator.CreateInstance(webHttpServiceHostFactory);
        hostFactory.Configuration = httpHostConfiguration;
        return new ServiceRoute(routePrefix, (ServiceHostFactoryBase)hostFactory, serviceType);
    }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        return lazyServiceRoute.Value.GetRouteData(httpContext);
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        return lazyServiceRoute.Value.GetVirtualPath(requestContext, values);
    }

    public Type ServiceType
    {
        get { return serviceType; }
    }

    public string RoutePrefix
    {
        get { return routePrefix; }
    }
}

This is a really simple class, it has the same constructors than the original “ServiceRoute” but it delays the creation of the ServiceRoute until the first usage as a route (see the field lazyServiceRoute). On the other hand LazyServiceRoute exposes the ServiceType and the RoutePrefix.

To get some syntax sugar I created the following extension methods to the RouteCollection:

public static class RouteTableExtensions
{
    public static void AddLazyServiceRoute<T>(
                this RouteCollection routeCollection, 
                string routePrefix, 
                HttpHostConfiguration httpHostConfiguration)
    {
        routeCollection.Add(new LazyServiceRoute(routePrefix, httpHostConfiguration, typeof(T)));
    }

    public static string GetRoutePrefixForType<T>(this RouteCollection routeCollection)
    {
        var routeServiceType = routeCollection
                                    .OfType<IPrefixedRouteType>()
                                    .FirstOrDefault(r => r.ServiceType == typeof (T));
        if(routeServiceType != null) return routeServiceType.RoutePrefix;
        return null;
    }
}

The first method is a shortcut for inserting a LazyServiceRoute to the route collection. The second one returns the prefix for a given resource type.

Finally the implementation of the ResourceLinker is pretty straightforward (despite the amount of reflection)

public interface IResourceLinker
{
    Uri GetUri<T>(Expression<Action<T>> restMethod);
}

public class ResourceLinker : IResourceLinker
{
    private readonly Uri baseUri;
    
    public ResourceLinker()
        : this(ConfigurationManager.AppSettings["BaseUri"])
    {}

    public ResourceLinker(string baseUri)
    {
        this.baseUri = new Uri(baseUri, UriKind.Absolute);
    }

    public Uri GetUri<T>(Expression<Action<T>> restMethod)
    {
        var methodCallExpression = (MethodCallExpression) restMethod.Body;
        var uriTemplateForMethod = GetUriTemplateForMethod(methodCallExpression.Method);

        var args = methodCallExpression.Method
            .GetParameters()
            .Where(p => uriTemplateForMethod.Contains("{" + p.Name + "}"))
            .ToDictionary(p => p.Name, p => ValuateExpression(methodCallExpression, p));

        var prefix = RouteTable.Routes.GetRoutePrefixForType<T>();
        var newBaseUri = new Uri(baseUri, prefix);
        var uriMethod = new UriTemplate(uriTemplateForMethod, true);
        return uriMethod.BindByName(newBaseUri, args);
    }

    private static string ValuateExpression(MethodCallExpression methodCallExpression, ParameterInfo p)
    {
        var argument = methodCallExpression.Arguments[p.Position];
        var constantExpression = argument as ConstantExpression;
        if(constantExpression != null) return constantExpression.Value.ToString();

        //var memberExpression = (argument as MemberExpression);
        var lambdaExpression = Expression.Lambda(argument, Enumerable.Empty<ParameterExpression>());
        var result = lambdaExpression.Compile().DynamicInvoke().ToString();
        return result;
    }

    private static string GetUriTemplateForMethod(MethodInfo method)
    {
        var webGet = method.GetCustomAttributes(true).OfType<WebGetAttribute>().FirstOrDefault();
        if (webGet != null) return webGet.UriTemplate ?? method.Name;

        var webInvoke = method.GetCustomAttributes(true).OfType<WebInvokeAttribute>().FirstOrDefault();
        if (webInvoke != null) return webInvoke.UriTemplate ?? method.Name;

        throw new InvalidOperationException(string.Format("The method {0} is not a web method.", method.Name));
    }
}

And the code for the Post method is:

[WebInvoke(UriTemplate = "", Method = "POST")]
public Contact Post(Contact contact, HttpResponseMessage response)
{
    this.repository.Post(contact);
    response.StatusCode = HttpStatusCode.Created;
    response.Header.Location =
       resourceLinker.Get<ContactResource>(cr => cr.Get(contact.Id, null));
    return contact;
}

(assuming you inject IResourceLinker in your resource class)

Testing

When I was about to write my first test with the IResourceLinker I tried to mock it. But then I figure out that is better to use the real implementation along with the real routes.

The first step is to extract the RouteTable configuration to another class;

public static class RouteConfigurator
{
    public static void Configure(HttpHostConfiguration configuration)
    {
        RouteTable.Routes.AddServiceRoute<ContactResource>("contact", configuration);
        RouteTable.Routes.AddServiceRoute<ContactsResource>("contacts", configuration);
    }
}

Then, we can write a base test fixture like this:

public class ResourceBaseTestFixture
{
    protected const string SampleHostRoute 
        = "http://foo.bar";
    protected IResourceLinker resourceLinker 
        = new ResourceLinker(SampleHostRoute);

    [TestFixtureSetUp]
    public void SetUp()
    {
        RouteTableConfigurator.Configure(null);    
    }

    [TestFixtureSetUp]
    public void TearDown()
    {
        RouteTable.Routes.Clear();
    }
}

And then you can test as follows:

[Test]
public void WhenPOSTingAContactThenReturn202AndTheLocationOfTheContact()
{
    //initilization and mock of the repository.

    var httpResponseMessage = new HttpResponseMessage(); 
    
    //act
    resource.Post(new Contact { .... }, httpResponseMessage);

    string locationOfTheNewContact =
        resourceLinker.GetUri<ContactResource>(cr => cr.Get(123, null)).ToString();

    httpResponseMessage.Satisfy(r => r.StatusCode == HttpStatusCode.Created
                                  && r.Headers.Location.ToString() == locationOfTheNewContact);
}

And then I realized the first thing I should write when creating a rest service will be something like this:

[Test]
public void TheRouteForPostAContactShouldBeOk()
{
    resourceLinker.GetUri<Contacts>(cr => cr.Create(null, null)).ToString()
        .Should().Be.EqualTo(SampleHostRoute + "/Contacts");
}

[Test]
public void TheRouteForRetrievingASingleContactShouldBeOk()
{
    resourceLinker.GetUri<Contact>(cr => cr.Get(123, null)).ToString()
        .Should().Be.EqualTo(SampleHostRoute + "/Contact/123");
}

But that is a matter of taste, I guess Sonrisa

Happy RESTing and stay in sync, I’ll start writing some articles about WCF.

| More

I’ve created a new nuget package; “NHibernate.SetForNet4”.

The package is only one file that will be inserted in your project. This class contains the implementation for the Set<T> and SortedSet<T>.

After you install NHibernate.SetForNet4; the only thing you have to do is to add the collection factory to your configuration as follows:

configuration.Properties[Environment.CollectionTypeFactoryClass] 
        = typeof(Net4CollectionTypeFactory).AssemblyQualifiedName; 

this is a sample mapping:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
        assembly="NHibernateSetForNet4"
        namespace="NHibernateSetForNet4">
  <class name="Person">
    <id name="Id">
      <generator class="hilo"/>
    </id>
    
    <property name="Name" />
    
    <property name="Age" />

    <set name="Tags" access="field.camelcase">
      <key column="PersonId" />
      <element column="Tag" />
    </set>

    <set name="Childs" 
        access="field.camelcase" 
        cascade="persist" 
        sort="PersonByAgeComparator">
      <key column="ParentId" />
      <one-to-many class="Person" />
    </set>

  </class>
</hibernate-mapping>

this is the class:

public class Person
{
    private readonly ISet<string> tags 
        = new HashSet<string>();
    private readonly ISet<Person> childs 
        = new SortedSet<Person>(new PersonByAgeComparator());

    public virtual int Id { get; set; }

    public virtual string Name { get; set; }

    public virtual int Age { get; set; }

    public virtual ISet<string> Tags
    {
        get { return tags; }
    }

    public virtual ISet<Person> Childs
    {
        get
        {
            return childs;
        }
    }
}

ISet<T>, HashSet<T> and SortedSet<T> are from System.Collections.Generics (.Net 4).

All these tests are green:

[TestFixture]
public class Fixture
{
    private ISessionFactory sessionFactory;
    private int personId;

    [TestFixtureSetUp]
    public void SetUp()
    {
        var configuration = new Configuration();
        configuration.Properties[Environment.CollectionTypeFactoryClass]
                = typeof(Net4CollectionTypeFactory).AssemblyQualifiedName;
        configuration.Configure();
        

        var schemaExport = new SchemaExport(configuration);
        schemaExport.Execute(true, true, false);
        sessionFactory = configuration.BuildSessionFactory();
        InitializeData();
    }

    private void InitializeData()
    {
        using (var s = sessionFactory.OpenSession())
        using (var tx = s.BeginTransaction())
        {
            var person = new Person
            {
                Name = "Pipo"
            };
            person.Childs.Add(new Person { Name = "Jose", Age = 1 });
            person.Childs.Add(new Person { Name = "Juan", Age = 5 });
            person.Childs.Add(new Person { Name = "Francisco", Age = 10 });

            person.Tags.Add("one");
            person.Tags.Add("two");
            person.Tags.Add("three");

            s.Persist(person);
            personId = person.Id;
            tx.Commit();
        }
    }

    [Test]
    public void CanGetAPersonWithTags()
    {
        using(var s = sessionFactory.OpenSession())
        using (s.BeginTransaction())
        {
            var person = s.Get<Person>(personId);
            person.Tags.Should().Have.SameValuesAs("one", "two", "three");
        }
    }
    
    [Test]
    public void SortedSetShouldWork()
    {
        using (var s = sessionFactory.OpenSession())
        using (s.BeginTransaction())
        {
            var person = s.Get<Person>(personId);
            person.Childs
                .Select(p => p.Age).ToArray()
                .Should().Have.SameSequenceAs(10, 5, 1);
        }
    }


    [Test]
    public void LazyLoadShouldWork()
    {
        using (var s = sessionFactory.OpenSession())
        using (s.BeginTransaction())
        {
            var person = s.Get<Person>(personId);
            s.Statistics.EntityCount.Should().Be.EqualTo(1);
            person.Childs.ToArray();
            s.Statistics.EntityCount.Should().Be.EqualTo(4);

        }
    }
}

The implementation of the proxy collections is a copy from the Iesi version. Let me know if you find some bug. The raw code is here.

Note: you still need Iesi.Collections.dll somewhere because nhibernate internals are tied to these collections, but you don’t longer need to reference it in your domain.

| More