Wednesday, November 5, 2014

Minimalistic Architecture

Here's a recommended minimalistic and minimum layers for a modern day line of business applications, especially the SPA ones

  1. App
  2. RichDomainModel - emphasis on rich
  3. RichDomainModel.Test
  4. RichDomainModelMapping
  5. Dto
  6. UnitTestFriendlyDal - Domain Access Layer, emphasis on unit-test friendly

    1. App

    • Hosts the UI
    • Serves DTOs as JSON to browser using ASP.NET Web API. ASP.NET Web API gets and pushes DTOs to rich domain models
    • Uses DTOs for data bag between UI and domain models
    • For wiring dependencies, LightInject is highly recommended, it's a very capable IoC/DI container. For AOP concerns, LightInject has interception capability
      • References RichDomainModel, Dto, LightInject, NHibernate


      2. RichDomainModel

      • Receives and returns DTOs to App project
      • Sample implementation:

      using Dto;
      
      using System.Collections.Generic;
      using System.Linq;
      using UnitTestFriendlyDal;
      
      namespace Domain
      {
          public static partial class ProductionDomain
          {
              public class ProductCategory
              {
                  public int    ProductCategoryId   { get; set; }
                  public string ProductCategoryName { get; set; }
      
                  public static IEnumerable<ProductionDto.ProductCategory> GetAll(IDomainAccess ds)
                  {
                      // http://www.ienablemuch.com/2014/10/proper-way-to-query-reference-entity.html
                      return ds.Query<ProductCategory>().MakeCacheable().ToList()
                          .Select(x => new ProductionDto.ProductCategory { Id = x.ProductCategoryId, Name = x.ProductCategoryName }); 
                  }     
              }
          }
      }
      

      • Has no virtual keyword on domain models' members even though NHibernate need domain models' members to be virtual. Uses Virtuosity.Fody to automatically make the domain models' members virtual
      • Though I mentioned above I love the word The, it's better to use an apt naming convention for the domain models. For AdventureWorks example, the tables HumanResources.Department, HumanResources.Employee, Person.Address, Person.Person and Production.Product tables domain models counterparts are: HumanResourcesDomain.Department, HumanResourcesDomain.Employee, PersonDomain.Address, PersonDomain.Person, ProductionDomain.Product. 
      • Do note that the names with Domain suffix are static partial classes, not namespaces, to see why static partial classes are better than namespace, see the link above. As for the need to use suffix/prefix, we cannot nest a class inside another class if it has the same name as the outer class
      • References Dto and UnitTestFriendlyDal only


      3. RichDomainModel.Test

      • Tests the business logic / behavior of the rich domain models
      • References RichDomainModel, RichDomainModelMapping, NHibernate, UnitTestFriendlyDal


      4. RichDomainModelMapping

      • Maps relational entities to RichDomainModel
      • References RichDomainModel and NHibernate only

      5. Dto - data bag between UI and rich domain model


      6. UnitTestFriendlyDal

      • DAL is not data access layer nor repository. This is just a domain access layer that needed its Linq be mockable. The data access layer / repository is NHibernate itself, no need to abstract NHibernate. Don't pile abstractions after abstractions on top of NHibernate, especially if the ORM has a repository, unit-of-work and data access layer built in
      • This is just a thin layer for ORM. NHibernate's .Query (Linq) is an extension method, extension methods can't be mocked properly, hence this interface is created. Abstracting the ORM is not the goal, it's the testability that we are after. Had NHibernate's .Query is not an extesion method, it can be mocked properly, this layer will not be needed. There's no need to add unnecessary abstractions on top of a capable ORM
      • References NHibernate only


      Here's a sample of an SPA stack that applies the layers above



      Sample Code: https://github.com/MichaelBuen/DemoSpaArchitectureMvp



      Multi-tenancy concern

      For multi-tenancy, it's better not to use schema on NHibernate. NHibernate doesn't have the capability yet to do proper multi-tenancy, Hibernate has

      Shoehorning schema on NHibernate's ISessionFactory as a mechanism to do multi-tenancy would entail each tenant to have their own session factory. Disadvantage being, as the second level cache for common reference tables amongst tenants have a copy on each tenant's session factory, the second-level cache can't be shared effectively, or can't be shared at all. So changes on common reference tables on one tenant will not appear on other tenants' second level cache. On the other hand, if we isolate the common reference table to one session factory only, the drawback is we cannot navigate nor join tenant entities to those common reference tables as those entities live in their own session factory

      I'll expound and make a simulation of this on another post


      Database schema is a bit fancy as a multi-tenancy mechanism, especially if the ORM is not yet capable of mapping entities to schema on-the-fly or elegantly

      So for now on NHibernate, it's better to use filters for multi-tenancy concerns



      Naming guideline

      http://www.ienablemuch.com/2013/01/when-your-codes-names-are-running-afoul.html



      Happy Coding!

      Tuesday, October 28, 2014

      WCF + LightInject + NHibernate (part 2 of 2)

      On the part 1 of this post, I showed you how to integrate WCF and LightInject together. On this last part, I'll show you how to integrate NHibernate to them


      This has 12 steps, let's begin


      1. To continue, let's add a DTO project using Class Library project, name it Dtos. Delete Class1.cs

      Add reference to System.Runtime.Serialization assembly

      Add a DTO class, name it PersonDto.Member.cs. Static classes enforce schema-like organization of domain models / DTOs

      using System.Runtime.Serialization;
       
      namespace Dtos
      {
          public static partial class PersonDto
          {
              [DataContract]
              public class Member
              {
                  [DataMember]
                  public int    MemberId   { get; set; }
                  [DataMember]
                  public string MemberName { get; set; }
              }
          }
      }
      


      2. On ServiceContracts project, add reference to Dtos project

      Then add PersonContract.IMemberService.cs interface:
      using Dtos;
      using System.Collections.Generic;
      using System.ServiceModel;
       
      namespace ServiceContracts
      {
          public static partial class PersonContract
          {
       
              [ServiceContract]
              public interface IMemberService
              {
                  [OperationContract]
                  string GetMembership();
       
       
                  [OperationContract]
                  IEnumerable<PersonDto.Member> GetMembers();
              }
          }
      }
      


      3. On ServiceImplementations project, add reference to Dtos project

      Then add implementation for PersonContract.IMemberService interface, name it PersonImplementation.MemberService.cs, use the following code:
      using System.Collections.Generic;
       
      namespace ServiceImplementations
      {
          public static partial class PersonImplementation
          {
              [System.ServiceModel.ServiceBehavior(InstanceContextMode = System.ServiceModel.InstanceContextMode.PerCall)]
              public class MemberService : ServiceContracts.PersonContract.IMemberService
              {
       
                  IEnumerable<Dtos.PersonDto.Member> ServiceContracts.PersonContract.IMemberService.GetMembers()
                  {
                      yield return new Dtos.PersonDto.Member { MemberId = 1, MemberName = "John" };
                      yield return new Dtos.PersonDto.Member { MemberId = 2, MemberName = "Paul" };
                      yield return new Dtos.PersonDto.Member { MemberId = 3, MemberName = "George" };
                      yield return new Dtos.PersonDto.Member { MemberId = 4, MemberName = "Ringo" };
                  }
       
                  string ServiceContracts.PersonContract.IMemberService.GetMembership()
                  {
                      return "Avengers";
                  }
              }
          }
      }
      


      4. On AppService, open ServiceHostingEnvironment.tt, then save it even there's no changes on its code. Saving the text template will trigger the regeneration of the ServiceHostingEnvironment.config. The updated ServiceHostingEnvironment.config shall look like this:

      <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
          <serviceActivations>
       
              <add relativeAddress="PersonImplementation.MemberService.svc" service="ServiceImplementations.PersonImplementation+MemberService" factory="AppService.LightInjectServiceHostFactory"/>
              <add relativeAddress="SampleService.svc" service="ServiceImplementations.SampleService" factory="AppService.LightInjectServiceHostFactory"/>
             
          </serviceActivations>
      </serviceHostingEnvironment>
      


      5. Run AppService

      To test, run WcfTestCLient, path is: "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\WcfTestClient.exe"

      Add Service on My Service Projects, then use this endpoint address: http://localhost:50549/PersonImplementation.MemberService.svc

      Invoke GetMembers(), you shall see this output:




      6. On NHibernate integration, step 0, run this DDL script:
      /*
      
      drop table Person.Member;
      drop schema Person;
      
      */
      
      create schema Person;
      
      go
      
      
      create table Person.Member
      (
      MemberId int not null identity(1,1),
      MemberName nvarchar(100) not null,
      
      
      constraint pk_Person_Member primary key(MemberId)
      );
      
      go
      
      
      insert into Person.Member(MemberName) values
      ('Ironman'),
      ('Captain America'),
      ('Thor'),
      ('Hulk');
      
      go
      
      



      7. NHibernate's Linq is using extension method, and as such is virtually impossible to mock properly. With that said, we need to add a thin layer for accessing NHibernate, which can be mocked if we need to unit test the rich domain model's behavior

      For that thin layer, create a class library project, name it UnitTestFriendlyDal

      Add NHibernate from NuGet Packages

      Create a class file, name it DomainAccess.cs. Then use this code on DomainAccess.cs:

      using System;
      using System.Linq;
      
      using NHibernate.Linq;
      
      namespace UnitTestFriendlyDal
      {
      
          public interface IDomainAccessFactory
          {
              IDomainAccess OpenDomainAccess();
          }
      
          public class DomainAccessFactory : IDomainAccessFactory
          {
              NHibernate.ISessionFactory _sessionFactory;
      
              public DomainAccessFactory(NHibernate.ISessionFactory sessionFactory)
              {
                  _sessionFactory = sessionFactory;
              }
      
              public IDomainAccess OpenDomainAccess()
              {
                  return new DomainAccess(_sessionFactory);
              }
          }
      
      
          public interface IDomainAccess : IDisposable
          {
              IQueryable<T> Query<T>();
              T Get<T>(object id);
              T Load<T>(object id);
              object Save(object transientObject);
              void Evict<T>(object id);
          }
      
          class DomainAccess : IDomainAccess
          {
      
              NHibernate.ISessionFactory _sessionFactory;
              NHibernate.ISession _session;
              NHibernate.ITransaction _transaction;
      
      
      
      
              public DomainAccess(NHibernate.ISessionFactory sessionFactory)
              {
                  _sessionFactory = sessionFactory;
                  _session = _sessionFactory.OpenSession();
                  _transaction = _session.BeginTransaction();
              }
      
      
              IQueryable<T> IDomainAccess.Query<T>()
              {
                  return _session.Query<T>();
              }
      
      
              T IDomainAccess.Get<T>(object id)
              {
                  return _session.Get<T>(id);
              }
      
              T IDomainAccess.Load<T>(object id)
              {
                  return _session.Load<T>(id);
              }
      
      
      
              void IDomainAccess.Evict<T>(object id)
              {
                  _sessionFactory.Evict(typeof(T), id);
              }
      
      
      
              object IDomainAccess.Save(object transientObject)
              {
                  return _session.Save(transientObject);
              }
      
      
              // Because transaction is a cross-cutting concern. It should be automated
              void IDisposable.Dispose()
              {
                  // http://www.hibernatingrhinos.com/products/nhprof/learn/alert/donotuseimplicittransactions
      
                  _transaction.Commit();
                  _transaction.Dispose();
                  _session.Dispose();
              }
      
      
          }//DomainAccess
      
      
          public static class LinqExtensionMethods
          {
              public static IQueryable<T> GetPage<T>(this IQueryable<T> query, int pageLimit, int pageNumber)
              {
                  var paged = query.Take(pageLimit).Skip(pageLimit * (pageNumber - 1));
      
                  return paged;
              }
          }
      
      
          /// <summary>
          /// cross-cutting concern   
          /// MakeCacheable replaces Cacheable, so IQueryable detection provider can be done here
          /// Can't use NHibernate's built-in .Cacheable on non-NHibernate IQueryable, it will throw an error   
          /// </summary>
          public static class NHibernateLinqExtensionMethods
          {
              public static IQueryable<T> MakeCacheable<T>(this IQueryable<T> query)
              {
                  if (query.Provider.GetType() == typeof(NHibernate.Linq.DefaultQueryProvider))
                      query = query.Cacheable();
      
                  return query;
              }
      
      
          }
      
      }
      


      8. Create a Class Library project. Name it RichDomainModels. Then delete Class1.cs

      Then add reference to Dtos and UnitTestFriendlyDal

      Add Virtuosity.Fody to the project, this AOP component saves us the need of adding virtual to every members of the domain model. All members of the domain models are required to be virtual by Nhibernate. With Virtuosity.Fody, all members are automagically made virtual for us, so we don't have to type virtual on each members anymore



      Add a class file, name it PersonDomain.Member.cs, then use the folllowing code. Notice that we don't add virtual to Member's MemberId and MemberName, that's courtesy of Virtuosity.Fody


      As for using static partial class (see PersonDomain on following code) instead of using namespace, we use static class to enforce schema-like way to group related domain models, namespace could be bypassed. Think of AdventureWorks database grouping related tables into their own schema


      using Dtos;
      using UnitTestFriendlyDal;
      
      using System.Linq;
      using System.Collections.Generic;
      
      
      namespace RichDomainModels
      {
          public static partial class PersonDomain
          {
              public class Member
              {
                  public int    MemberId   { get; set; }
                  public string MemberName { get; set; }
      
      
                  public static IEnumerable<PersonDto.Member> GetMembers(IDomainAccess da)
                  {
                      var list = da.Query<PersonDomain.Member>().MakeCacheable().ToList()
                          .Select(x =>
                              new PersonDto.Member
                              {
                                  MemberId = x.MemberId,
                                  MemberName = x.MemberName
                              });
      
                      return list;
                  }
              }
      
          }
      }
      

      9. Add a Class Library project, name it RichDomainModelsMapping. Then delete Class1.cs

      Add NHibernate and NHibernate.Caches.SysCache to the project:



      Add reference to RichDomainModels

      Add a class file, name it Mapper.cs, then use the following code:
      using NHibernate.Cfg; // .DatabaseIntegration extension method
      
      using System.Linq;
      
      
      namespace RichDomainModelsMapping
      {
          public static class Mapper
          {
      
              static NHibernate.ISessionFactory _sessionFactory = Mapper.BuildSessionFactory();
      
      
              // call this on production
              public static NHibernate.ISessionFactory SessionFactory
              {
                  get { return _sessionFactory; }
              }
      
      
              public static NHibernate.ISessionFactory BuildSessionFactory(bool useUnitTest = false)
              {
      
                  var mapper = new NHibernate.Mapping.ByCode.ConventionModelMapper();
                  mapper.IsEntity((t, declared) => t.Namespace == "RichDomainModels");
      
                  mapper.BeforeMapClass += mapper_BeforeMapClass;
                  mapper.BeforeMapProperty += mapper_BeforeMapProperty;
                  mapper.BeforeMapManyToOne += mapper_BeforeMapManyToOne;
                  mapper.BeforeMapBag += mapper_BeforeMapBag;
      
      
      
      
                  var cfg = new NHibernate.Cfg.Configuration();
      
      
      
                  // .DatabaseIntegration! Y U EXTENSION METHOD?!
                  cfg.DataBaseIntegration(c =>
                  {
                      // SQL Server
                      c.Driver<NHibernate.Driver.SqlClientDriver>();
                      c.Dialect<NHibernate.Dialect.MsSql2008Dialect>();
                      c.ConnectionString = "Server=.;Database=PlayTheWcfServiceApp;Trusted_Connection=True";
      
      
                      if (useUnitTest)
                      {
                          c.LogSqlInConsole = true;
                          c.LogFormattedSql = true;
                      }
                  });
      
      
      
                  System.Collections.Generic.IEnumerable<System.Type> entities =
                      typeof(RichDomainModels.PersonDomain.Member).Assembly.GetExportedTypes()
      
                          // exclude static classes (the schema name)
                      // this will still include the non-static class inside of static classes, i.e., the domain models
                          .Where(x => !(x.IsAbstract && x.IsSealed));
      
                  NHibernate.Cfg.MappingSchema.HbmMapping mapping = mapper.CompileMappingFor(entities);
      
      
                  cfg.AddMapping(mapping);
      
                  cfg.Cache(x =>
                  {
                      // SysCache is not stable on unit testing
                      if (!useUnitTest)
                      {
                          x.Provider<NHibernate.Caches.SysCache.SysCacheProvider>();
      
                          // I don't know why SysCacheProvider is not stable on simultaneous unit testing,
                          // might be SysCacheProvider is just giving one session factory, so simultaneous test see each other caches
                          // This solution doesn't work: http://stackoverflow.com/questions/700043/mstest-executing-all-my-tests-simultaneously-breaks-tests-what-to-do                   
                      }
                      else
                      {
                          // This is more stable in unit testing
                          x.Provider<NHibernate.Cache.HashtableCacheProvider>();
                      }
      
      
                      // http://stackoverflow.com/questions/2365234/how-does-query-caching-improves-performance-in-nhibernate
      
                      // Need to be explicitly turned on so the .Cacheable directive on Linq will work:                   
                      x.UseQueryCache = true;
                  });
      
      
      #if DEBUG
                  if (useUnitTest)
                      cfg.SetInterceptor(new NHSQLInterceptor());
      #endif
      
      
      
                  //new NHibernate.Tool.hbm2ddl.SchemaUpdate(cfg).Execute(useStdOut: false, doUpdate: true);
      
      
                  //using (var file = new System.IO.FileStream(@"c:\x\ddl.txt",
                  //       System.IO.FileMode.Create,
                  //       System.IO.FileAccess.ReadWrite))
                  //using (var sw = new System.IO.StreamWriter(file))
                  //{
                  //    new SchemaUpdate(cfg)
                  //        .Execute(sw.Write, false);
                  //}
      
      
                  NHibernate.ISessionFactory sf = cfg.BuildSessionFactory();
      
      
                  return sf;
              }
      
      #if DEBUG
              class NHSQLInterceptor : NHibernate.EmptyInterceptor
              {
                  // http://stackoverflow.com/questions/2134565/how-to-configure-fluent-nhibernate-to-output-queries-to-trace-or-debug-instead-o
                  public override NHibernate.SqlCommand.SqlString OnPrepareStatement(NHibernate.SqlCommand.SqlString sql)
                  {
      
                      Mapper.NHibernateSQL = sql.ToString();
                      return sql;
                  }
      
              }
      
              public static string NHibernateSQL { get; set; }
      #endif
      
      
      
              static void mapper_BeforeMapBag(
                  NHibernate.Mapping.ByCode.IModelInspector modelInspector,
                  NHibernate.Mapping.ByCode.PropertyPath member,
                  NHibernate.Mapping.ByCode.IBagPropertiesMapper propertyCustomizer)
              {
      
                  propertyCustomizer.Cache(cacheMapping => cacheMapping.Usage(NHibernate.Mapping.ByCode.CacheUsage.ReadWrite));
      
                  propertyCustomizer.Lazy(NHibernate.Mapping.ByCode.CollectionLazy.Extra);
      
                  /*
                   * class Person
                   * {
                   *      IList<Hobby> Hobbies
                   * }
                   *
                   *
                   */
      
                  string parentEntity = member.LocalMember.DeclaringType.Name; // this gets the Person
                  string foreignKey = parentEntity + "Id";
                  propertyCustomizer.Key(keyMapping => keyMapping.Column(foreignKey));
      
      
                  // http://www.ienablemuch.com/2014/10/inverse-cascade-variations-on-nhibernate.html
                  // best persistence approach: Inverse+CascadeAll
                  propertyCustomizer.Inverse(true);
                  propertyCustomizer.Cascade(NHibernate.Mapping.ByCode.Cascade.All);
      
              }
      
      
      
              static void mapper_BeforeMapManyToOne(
                  NHibernate.Mapping.ByCode.IModelInspector modelInspector,
                  NHibernate.Mapping.ByCode.PropertyPath member,
                  NHibernate.Mapping.ByCode.IManyToOneMapper propertyCustomizer)
              {
                  /*
                  
                      public class Product
                      {
                          protected internal  int                                ProductId       { get; set; }
      
                          public              ProductionDomain.ProductCategory   ProductCategory { get; protected internal set; }
                          public              string                             ProductName     { get; protected internal set; }
                      }
                  
                   */
      
                  // ProductCategory property name maps to ProductCategoryId column name
                  propertyCustomizer.Column(member.ToColumnName() + "Id");
              }
      
              static void mapper_BeforeMapProperty(
                  NHibernate.Mapping.ByCode.IModelInspector modelInspector,
                  NHibernate.Mapping.ByCode.PropertyPath member,
                  NHibernate.Mapping.ByCode.IPropertyMapper propertyCustomizer)
              {
                  //string postgresFriendlyName = member.ToColumnName().ToLowercaseNamingConvention();
                  //propertyCustomizer.Column(postgresFriendlyName);    
      
              }
      
              static void mapper_BeforeMapClass(NHibernate.Mapping.ByCode.IModelInspector modelInspector,
                  System.Type type,
                  NHibernate.Mapping.ByCode.IClassAttributesMapper classCustomizer)
              {
      
                  classCustomizer.Cache(cacheMapping => cacheMapping.Usage(NHibernate.Mapping.ByCode.CacheUsage.ReadWrite));
      
                  string fullName = type.FullName; // example: RichDomainModels.ProductionDomain+Product
      
                  string[] fullnameSplit = fullName.Split('+');
      
                  string schemaName;
                  string className;
                  if (fullnameSplit.Length == 2) // The domain model is in a schema (e.g., ProductionDomain)
                  {
                      schemaName = fullnameSplit[0].Split('.').Last();
                      schemaName = schemaName.Substring(0, schemaName.Length - "Domain".Length); // removes the suffix Domain
                      className = fullnameSplit[1];
                  }
                  else // domain model is not inside schema
                  {
                      schemaName = "dbo";
                      className = fullnameSplit[0].Split('.').Last();
                  }
      
                  // Last() skips the other namespace(s). 3 skips the word The
      
      
                  string tableFullname = schemaName + "." + className;
                  classCustomizer.Table(tableFullname);
      
      
      
                  System.Reflection.MemberInfo mi;
      
                  System.Reflection.MemberInfo[] memberInfos = type.GetMember(className + "Id",
                      System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
      
      
                  if (memberInfos.Length == 1)
                  {
                      mi = memberInfos[0];
                  }
                  else
                  {
      
                      System.Reflection.MemberInfo[] defaultIdNames = type.GetMember("Id",
                          System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
      
      
      
      
                      if (defaultIdNames.Length == 0)
                          throw new System.Exception("Impossible. Should have an ID");
                      else if (defaultIdNames.Length == 1)
                          mi = defaultIdNames[0];
                      else
                          throw new System.Exception("Houston we have a problem. Why there's multiple ID property?");
      
                  }
      
                  classCustomizer.Id(mi,
                      idMapper =>
                      {
                          idMapper.Column(mi.Name);
                          idMapper.Generator(NHibernate.Mapping.ByCode.Generators.Identity);
                      });
      
      
              }
      
          } // Mapper
      }
      



      10. On AppService

      Add NHibernate to the project, and add reference to RichDomainModelsMapping and UnitTestFriendlyDal

      On Global.asax.cs, add the wiring of NHibernate ISessionFactory and Domain Access Layer, line 38 and 39:
      using System;
      using System.Linq;
      using UnitTestFriendlyDal;
      
      
      namespace AppService
      {
          public class Global : System.Web.HttpApplication
          {
      
              protected void Application_Start(object sender, EventArgs e)
              {
                  DependencyFactory.Container = new LightInject.ServiceContainer();
      
      
                  RegisterIocs();
              }
      
              static void RegisterIocs()
              {
      
                  //// Instead of manually adding each implementation:
                  //DependencyFactory.Container.Register<ServiceImplementations.ProductImplementation.ProductService>(new LightInject.PerRequestLifeTime());
                  //DependencyFactory.Container.Register<ServiceImplementations.PersonImplementation.MemberService>(new LightInject.PerRequestLifeTime());
      
                  // Just do this:
                  var serviceImplementations = typeof(ServiceImplementations.SampleService).Assembly.GetTypes()
                      .Where(t => t.GetInterfaces()
                          .Any(i => i.GetCustomAttributes(false)
                              .Any(a => a.GetType() == typeof(System.ServiceModel.ServiceContractAttribute))));
      
                  foreach (var item in serviceImplementations)
                  {
                      DependencyFactory.Container.Register(item, new LightInject.PerRequestLifeTime());
                  }
      
      
                  DependencyFactory.Container.Register<IDomainAccessFactory, DomainAccessFactory>(new LightInject.PerContainerLifetime());
                  DependencyFactory.Container.RegisterInstance<NHibernate.ISessionFactory>(RichDomainModelsMapping.Mapper.SessionFactory);
              }
          }
      }
      


      11. On ServiceImplementations, add reference to UnitTestFriendlyDal and RichDomainModels

      Then change the PersonImplementation.MemberService to this code:
      using System.Collections.Generic;
      using UnitTestFriendlyDal;
      
      namespace ServiceImplementations
      {
      
          public static partial class PersonImplementation
          {
              [System.ServiceModel.ServiceBehavior(InstanceContextMode = System.ServiceModel.InstanceContextMode.PerCall)]
              public class MemberService : ServiceContracts.PersonContract.IMemberService
              {
                  IDomainAccessFactory _daf;
      
                  public MemberService(IDomainAccessFactory daf)
                  {
                      _daf = daf;
                  }
      
      
                  IEnumerable<Dtos.PersonDto.Member> ServiceContracts.PersonContract.IMemberService.GetMembers()
                  {
                      using (var da = _daf.OpenDomainAccess())
                      {
                          return RichDomainModels.PersonDomain.Member.GetMembers(da);
                      }
                  }
      
                  string ServiceContracts.PersonContract.IMemberService.GetMembership()
                  {
                      return "Avengers";
                  }
              }
          }
      }
      

      12. Make sure the connection string is correct on RichDomainModelsMapping

      Run AppService

      To test, run WcfTestClient and click Invoke on GetMembers, you shall see the following:





      Complete code at: https://github.com/MichaelBuen/PlayWcfServiceApplication



      Happy Coding!

      WCF + LightInject + NHibernate (part 1 of 2)

      On this post I'll how you how to integrate WCF + LightInject + NHibernate

      The post is divided into two parts. The first post (this post) will be about WCF + LightInject only, so we can have basic infrastructure for WCF + IoC. We will tackle the domain model integration via NHibernate on the second part


      These are the seven layers of a WCF Service Application:
      * AppService
      * Dtos
      * RichDomainModels
      * RichDomainModelsMapping
      * ServiceContracts
      * ServiceImplementations
      * UnitTestFriendlyDal
      
      
      AppService - WCF Service Application
          
          Using LightInject for IoC/DI:
              Wires NHibernate and UnitTestFriendlyDal
              Wires IDomainAccessFactory to ServiceImplementations
              
          Generates svc based on ServiceImplementations
          Wires svc to its implementation using AppService.LightInjectServiceHostFactory
              
              
      Dtos - DTOs. References System.Runtime.Serialization only
      
          The data that travels across the wire
          
          
      RichDomainModels - References Dtos and UnitTestFriendlyDal only
      
      
          Contains the nouns and verbs of a domain
          
          Has no virtual keyword on domain models' members even NHibernate need domain models' members to be virtual. Uses Virtuosity.Fody to automatically make the domain models' members be virtual
      
          ORM-agnostic, e.g., has no access to NHibernate. Has access to UnitTestFriendlyDal only
          
          Receives and returns DTOs to WCF consumer
          
          
          
      RichDomainModelsMapping - References NHibernate and RichDomainModels only
      
          Maps relational entities to RichDomainModels
          
          
      ServiceContracts - References Dtos and System.ServiceModel only
      
          interface for ServiceImplementations
          
      ServiceImplementations - References Dtos, ServiceContract, RichDomainModels, UnitTestFriendlyDal and System.ServiceModel
              
          Just a thin layer for RichDomainModels, the main process are done on RichDomainModels
          
      UnitTestFriendlyDal - Domain Access Layer. References NHibernate only
      
          Just a thin layer for ORM(NHibernate), NHibernate's .Query is an extension method, it can't be mocked properly, hence this interface is created
          
      


      The part 1 of this how-to has three layers only; namely AppService, ServiceContracts and ServiceImplementations

      The part 2 has the seven layers detailed above



      Let's begin the part 1, this will just take us eight steps


      1. Create WCF Service Application, not WCF Service Library, name it AppService



      Delete IService1.svc and Service1.svc, we will move the contracts and implementation to their own assemblies




      2. Add Class Library project, name it ServiceContracts

      Add reference to System.ServiceModel assembly




      Delete Class1.cs, then add ISampleService interface, make it public:

      using System.ServiceModel;
       
      namespace ServiceContracts
      {
          [ServiceContract]
          public interface ISampleService
          {
              [OperationContract]
              string GetGreet();
          }
      }
      


      3. Add another Class Library project, name it ServiceImplementations, add reference to System.ServiceModel assembly too

      Add reference to ServiceContracts project




      Delete Class1.cs from ServiceImplementations project. Then add ISampleService implementation, name it SampleService, make it public:

      using System.ServiceModel;
      
      namespace ServiceImplementations
      {
          [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
          public class SampleService : ServiceContracts.ISampleService
          {
              string ServiceContracts.ISampleService.GetGreet()
              {
                  return "Hey " + System.Guid.NewGuid();
              }
          }
      }
      

      Here's how interface and implementation should look like:





      4. On AppService project, add LightInject from NuGet Packages:




      Then add reference to System.ServiceModel.Activation assembly

      Let's not make an apple pie from scratch, let's pattern our LightInject WCF dependency-injection from Jimmy Bogard's template for WCF+StructureMap integration. Create a new class file, name it Ioc.cs, then overwrite its content with these:

      using System;
       
      using System.ServiceModel;
      using System.ServiceModel.Dispatcher;
      using System.ServiceModel.Channels;
      using System.ServiceModel.Description;
      using System.ServiceModel.Activation;
       
       
       
      namespace AppService
      {
          public static class DependencyFactory
          {
              public static LightInject.IServiceContainer Container { get; set; }
          }
       
          public class LightInjectInstanceProvider : IInstanceProvider
          {
              readonly Type _serviceType;
       
              public LightInjectInstanceProvider(Type serviceType)
              {
                  _serviceType = serviceType;
       
              }
       
              object IInstanceProvider.GetInstance(InstanceContext instanceContext)
              {
                  return Resolve();
              }
       
              object IInstanceProvider.GetInstance(InstanceContext instanceContext, Message message)
              {
                  return Resolve();
              }
       
       
              object Resolve()
              {
                  var instance = DependencyFactory.Container.GetInstance(_serviceType);
                  return instance;
              }
       
       
              void IInstanceProvider.ReleaseInstance(InstanceContext instanceContext, object instance)
              {
                  var disposable = instance as IDisposable;
                  if (disposable != null)
                  {
                      disposable.Dispose();
                  }
              }
          }
       
          public class LightInjectServiceBehavior : IServiceBehavior
          {
              void IServiceBehavior.AddBindingParameters(
                  ServiceDescription serviceDescription,
                  ServiceHostBase serviceHostBase,
                  System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints,
                  BindingParameterCollection bindingParameters)
              {
              }
       
              void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
              {
                  foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
                  {
                      var cd = cdb as ChannelDispatcher;
                      if (cd != null)
                      {
                          foreach (EndpointDispatcher ed in cd.Endpoints)
                          {
                              ed.DispatchRuntime.InstanceProvider = new LightInjectInstanceProvider(serviceDescription.ServiceType);
                          }
                      }
                  }
              }
       
              void IServiceBehavior.Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
              {
              }
          }
       
          public class LightInjectServiceHost : ServiceHost
          {
       
              public LightInjectServiceHost(Type serviceType, params Uri[] baseAddresses)
                  : base(serviceType, baseAddresses)
              {
              }
       
              protected override void OnOpening()
              {
                  Description.Behaviors.Add(new LightInjectServiceBehavior());
                  base.OnOpening();
              }
       
          }
       
       
          public class LightInjectServiceHostFactory : ServiceHostFactory
          {
              protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
              {
                  return new LightInjectServiceHost(serviceType, baseAddresses);
              }
          }
       
      }
      

      5. Add Text Template to the project, name it ServiceHostingEnvironment.tt, then use the following:


      <#@ template debug="false" hostspecific="false" language="C#" #>
      <#@ assembly name="System.Core" #>
      <#@ assembly name="System.ServiceModel" #>
      <#@ assembly name="$(SolutionDir)\ServiceContracts\bin\Debug\ServiceContracts.dll" #>
      <#@ assembly name="$(SolutionDir)\ServiceImplementations\bin\Debug\ServiceImplementations.dll" #>
      <#@ import namespace="System.Linq" #>
      <#@ import namespace="System.Text" #>
      <#@ import namespace="System.Collections.Generic" #>
      <#@ output extension=".config" #>
      <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
          <serviceActivations>
      <#
                  var serviceImplementations = typeof(ServiceImplementations.SampleService).Assembly.GetTypes()
                      .Where(t => t.GetInterfaces()
                          .Any(i => i.GetCustomAttributes(false)
                              .Any(a => a.GetType() == typeof(System.ServiceModel.ServiceContractAttribute))));
       
      #>
       
      <#  foreach (var item in serviceImplementations)
          { 
              
              string fullName = item.FullName; // example: ServiceImplementations.PersonImplementation+MemberService
       
              string[] fullnameSplit = fullName.Split('+');
       
              string schemaName;
              string className;
       
              string serviceFullname;
       
              if (fullnameSplit.Length == 2) // The model service is in a schema (e.g., PersonImplementation static class)
              {
                  schemaName = fullnameSplit[0].Split('.').Last();
                  className = fullnameSplit[1];
       
                  serviceFullname = schemaName + "." + className;            
              }
              else // domain model is not inside schema
              {
                  serviceFullname = item.Name;
              }
       
              
          
      #>
              <add relativeAddress="<#=serviceFullname#>.svc" service="<#=item.FullName#>" factory="AppService.LightInjectServiceHostFactory"/>
      <#  } #>       
          </serviceActivations>
      </serviceHostingEnvironment>
      


      Following is the output of Text Template code above. Filename output is ServiceHostingEnvironment.config:


      <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
          <serviceActivations>
       
              <add relativeAddress="SampleService.svc" service="ServiceImplementations.SampleService" factory="AppService.LightInjectServiceHostFactory"/>
             
          </serviceActivations>
      </serviceHostingEnvironment>
      

      On web.config, remove the highlighted line..



      ..and replace it with:
      <serviceHostingEnvironment configSource="ServiceHostingEnvironment.config"/>
      


      You can ignore this warning in the project:



      6. On AppService, add reference ServiceContracts and ServiceImplementations




      Then add Global Application Class:



      Use this in Global Application Class (Global.asax.cs):
      using System;
      using System.Linq;
       
       
      namespace AppService
      {
          public class Global : System.Web.HttpApplication
          {
       
              protected void Application_Start(object sender, EventArgs e)
              {
                  DependencyFactory.Container = new LightInject.ServiceContainer();
       
       
                  RegisterIocs();
              }
       
              static void RegisterIocs()
              {
       
                  //// Instead of manually adding each implementation:
                  //DependencyFactory.Container.Register<ServiceImplementations.ProductImplementation.ProductService>(new LightInject.PerRequestLifeTime());
                  //DependencyFactory.Container.Register<ServiceImplementations.PersonImplementation.MemberService>(new LightInject.PerRequestLifeTime());
       
                  // Just do this:
                  var serviceImplementations = typeof(ServiceImplementations.SampleService).Assembly.GetTypes()
                      .Where(t => t.GetInterfaces()
                          .Any(i => i.GetCustomAttributes(false)
                              .Any(a => a.GetType() == typeof(System.ServiceModel.ServiceContractAttribute))));
       
                  foreach (var item in serviceImplementations)
                  {
                      DependencyFactory.Container.Register(item, new LightInject.PerRequestLifeTime());
                  }
       
       
       
              }
          }
      }
      


      7. Run the AppService

      You'll notice there is no .svc file(s) in the WCF Service application, it's served dynamically




      To verify it exists, visit .svc on the browser: http://localhost:50549/SampleService.svc, here's the result:



      8. Last step. To test, run WcfTestCLient, path is: "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\WcfTestClient.exe"



      Click GetGreet, then click Invoke. You shall see the following output:




      On second part of this post, I will show how to integrate NHibernate on this WCF Service application



      Complete code at: https://github.com/MichaelBuen/PlayWcfServiceApplication




      Happy Coding!

      Wednesday, October 22, 2014

      Simulating DryIoc's RegisterDelegate on LightInject

      DryIoc 2.0 has a way now to register runtime types where their instances are determined at the later time. If you are using older version of DryIoc you can use this solution.

      void RegisterWcfServices()
      {
          var binding = new System.ServiceModel.BasicHttpBinding();
          
          // get all interfaces
          foreach (var contractType in typeof(TheServiceContracts.IMemberService).Assembly.GetTypes())
          {                
              _container.RegisterDelegate(contractType,
                  r =>
                  {
                      var svcAddress = "http://localhost:1337/" + contractType.Name.Substring(1) + ".svc";
                      var endpointAddress = new System.ServiceModel.EndpointAddress(svcAddress);
      
                      return ServiceModelHelper.CreateService(contractType, binding, endpointAddress);
                      
                  }, Reuse.InResolutionScope);
      
          }
      }
      


      To simulate that in LightInject, use RegisterFallback
      void RegisterWcfServices()
      {
          var binding = new System.ServiceModel.BasicHttpBinding();
      
          System.Reflection.Assembly serviceAssembly = typeof(TheServiceContracts.IMemberService).Assembly;
      
          // Assuming TheServiceContracts assembly has interfaces only, the following code would suffice
          _container.RegisterFallback((t, s) => t.Assembly == serviceAssembly, 
              factory =>
              {
                  var svcAddress = "http://localhost:1337/" + factory.ServiceType.Name.Substring(1) + ".svc";
                  var endpointAddress = new System.ServiceModel.EndpointAddress(svcAddress);
      
                  return ServiceModelHelper.CreateService(factory.ServiceType, binding, endpointAddress);            
              }
           );            
      }
      


      However, LightInject's RegisterFallback hack is not quite the same as DryIoc's RegisterDelegate. With DryIoc.RegisterDelegate, the service types (e.g., contractType) are stored in lookups, so when the time come the service type needs to be resolved, the delegate that returns an object for the service type could be determined quickly


      Another problem with RegisterFallback is it is called lastly after LightInject determines the type is not registered at all, that could lead to performance problem. There's a good optimization though, once the unregistered type matches a RegisterFallback's condition, RegisterFallback's factory delegate is cached to the unregistered type, making the RegisterFallback's condition not to be evaluated again anymore


      Another potential performance problem, the code could be littered with lots of ifs if we want to target specific types, to wit:
      void RegisterWcfServices()
      {
          var binding = new System.ServiceModel.BasicHttpBinding();
          
          System.Reflection.Assembly serviceAssembly = typeof(TheServiceContracts.IMemberService).Assembly;
      
          _container.RegisterFallback((t, s) => 
                  t.Assembly == serviceAssembly 
                  || t == typeof(IThinkService), 
              factory =>
              {
                  if (factory.ServiceType.Assembly == serviceAssembly)
                  {
                      var svcAddress = "http://localhost:1337/" + factory.ServiceType.Name.Substring(1) + ".svc";
                      var endpointAddress = new System.ServiceModel.EndpointAddress(svcAddress);
      
                      return ServiceModelHelper.CreateService(factory.ServiceType, binding, endpointAddress);            
                  }
                  else if (factory.ServiceType == typeof(IThinkService))
                  {
                      // some specialized object construction here
      
                      // return the constructed object
                  }
                  else
                      return null;
              }
           );            
      }
      


      That lots of ifs could be avoided by registering specific types on their own RegisterFallback, e.g.,
      _container.RegisterFallback((t, s) => t.Assembly == serviceAssembly,
          factory =>
          {
              var svcAddress = "http://localhost:61930/" + factory.ServiceType.Name.Substring(1) + ".svc";
              var endpointAddress = new System.ServiceModel.EndpointAddress(svcAddress);
      
              object instance = ServiceModelHelper.CreateService(factory.ServiceType, binding, endpointAddress);
      
              return instance;
          });
      
      
      _container.RegisterFallback((t, s) => t == typeof(string),
            factory =>
            {
                return "Hello world";
            });
      


      However, multiple RegisterFallback could potentially cause a delay on app's cold start especially if there are too many of them. On the positive aspect, once the unregistered type matches a RegisterFallback condition, RegisterFallback's factory delegate is cached to the unregistered object, making the RegisterFallback's condition not to be evaluated again anymore, plus there's no more many ifs inside the factory delegate


      Another approach is to use LightInject's RegisterInstance:
      void RegisterWcfServices()
      {
          var binding = new System.ServiceModel.BasicHttpBinding();
              
          foreach (var contractType in typeof(TheServiceContracts.IMemberService).Assembly.GetTypes())
          {
              var svcAddress = "http://localhost:1337/" + contractType.Name.Substring(1) + ".svc";
              var endpointAddress = new System.ServiceModel.EndpointAddress(svcAddress);
      
              object instance = ServiceModelHelper.CreateService(contractType, binding, endpointAddress);
              _container.RegisterInstance(contractType, instance);
          }
      }
      

      However, that could potentially cause a delay on app's cold start too as instances for the interfaces are eagerly determined during IoC registration


      Adding RegisterDelegate functionality on LightInject is desirable



      Happy Coding!

      Monday, October 20, 2014

      Registering runtime types on DryIoc

      DryIoc is missing an API for registering a runtime type

      Hence we can't automate this WCF registration..

      _container.RegisterDelegate<TheServiceContracts.IProductService>(x => 
          (TheServiceContracts.IProductService) ServiceModelHelper.CreateService(
              typeof(TheServiceContracts.IProductService),  
              System.ServiceModel.BasicHttpBinding(), 
              new System.ServiceModel.EndpointAddress("http://localhost:1337/ProductService.svc")
          )
      , Reuse.InResolutionScope);
          
      _container.RegisterDelegate<TheServiceContracts.IMemberService>(x => 
          (TheServiceContracts.IMemberService) ServiceModelHelper.CreateService(
              typeof(TheServiceContracts.IMemberService), 
              new System.ServiceModel.BasicHttpBinding(), 
              new System.ServiceModel.EndpointAddress("http://localhost:1337/MemberService.svc")
          )
      , Reuse.InResolutionScope);
      
      _container.RegisterDelegate<TheServiceContracts.IOrderService>(x => 
          (TheServiceContracts.IOrderService) ServiceModelHelper.CreateService(
              typeof(TheServiceContracts.IOrderService), 
              new System.ServiceModel.BasicHttpBinding(), 
              new System.ServiceModel.EndpointAddress("http://localhost:1337/OrderService.svc")
          )
      , Reuse.InResolutionScope);
      


      ..into this:

      _container.Register<System.ServiceModel.BasicHttpBinding>(DryIoc.Reuse.Singleton, x => x.GetConstructor(new Type[] { }));
      
      foreach (var contractType in typeof(TheServiceContracts.IMemberService).Assembly.GetTypes())
      {
          _container.RegisterDelegate(contractType,
              r =>
              {
                  var binding = r.Resolve<System.ServiceModel.BasicHttpBinding>();
      
                  var svcAddress = "http://localhost:1337/" + contractType.Name.Substring(1) + ".svc";
                  var endpointAddress = new System.ServiceModel.EndpointAddress(svcAddress);
      
      
                  return ServiceModelHelper.CreateService(contractType, new System.ServiceModel.BasicHttpBinding(), endpointAddress);
              }, Reuse.InResolutionScope);
      
      }   
      


      And this available API in DryIoc can't be used, parameters in generics and casting must be determined at compile-time. Hence we can't pass the runtime type contractType variable as a parameter to generics and casting
      _container.Register<System.ServiceModel.BasicHttpBinding>(DryIoc.Reuse.Singleton, x => x.GetConstructor(new Type[] { }));
      
      foreach(var contractType in typeof(TheServiceContracts.IProductService).Assembly.GetTypes())
      {
          var binding = new System.ServiceModel.BasicHttpBinding();
          var endpointAddress = new System.ServiceModel.EndpointAddress("http://localhost:1337/" + contractType.SubString(1) + ".svc"); // removes the first letter I
          _container.RegisterDelegate<contractType>(r => 
              {
                  var binding = r.Resolve<System.ServiceModel.BasicHttpBinding>();
      
                  var svcAddress = "http://localhost:1337/" + contractType.Name.Substring(1) + ".svc";
                  var address = new System.ServiceModel.EndpointAddress(svcAddress);
                  
                  return (contractType) ServiceModelHelper.CreateService(contractType, binding, endpointAddress)
              }, Reuse.InResolutionScope);
      }
      


      To fix that, we need to simulate RegisterDelegate<T> during runtime


      First step, we should design how the additional API should look like. It should feel as close as possible to the convention of the original API:
      _container.RegisterDelegate<TheServiceContracts.IOrderService>(x => 
          (TheServiceContracts.IOrderService) ServiceModelHelper.CreateService(
              typeof(TheServiceContracts.IOrderService), 
              new System.ServiceModel.BasicHttpBinding(), 
              new System.ServiceModel.EndpointAddress("http://localhost:1337/OrderService.svc")
          )
      , Reuse.InResolutionScope);
      


      The additional API should be like this:
      _container.RegisterDelegate(contractType, x => 
          ServiceModelHelper.CreateService(
              contractType, 
              new System.ServiceModel.BasicHttpBinding(), 
              new System.ServiceModel.EndpointAddress("http://localhost:1337/OrderService.svc")
          )
      , Reuse.InResolutionScope);
      


      Then our API should be an extension method of the DryIoc.IResolver:
      public static class ResolverExtensionHelper
      {
          public static void RegisterDelegate(this DryIoc.IResolver resolver,
               Type contractType,
               Func<DryIoc.IResolver, object> objectConstructor,
               DryIoc.IReuse reuse = null, DryIoc.FactorySetup setup = null, string named = null)
          {
              ResolverBuilder.Build(container, contractType, objectConstructor, reuse, setup, named);
          }
      }
      


      You maybe wondering why we need to use two classes, ResolverBuilder and ResolverExtensionHelper, why not just do everything in ResolverExtensionHelper?

      We need to have the following code, we need to cast the objects generated(e.g., WCF proxy objects) in a delegate back to its dependency-injected type(e.g., is an interface) during runtime, which is not possible with the original RegisterDelegate<contractTypeHere>. So we need to have a mechanism that can cast runtime types:
      TService ConstructObjectThenCast<TService>(IResolver resolver)
      {
          var svc = (TService) this._objectConstructorDelegate(resolver);
          return svc;
      }
      


      And we cannot add lambda parameter (any parameter for that matter) on that method:
      TService ConstructObjectThenCast<TService>(IResolver resolver, 
          Func<IResolver, object> objectConstructorDelegate)
      {
          var svc = (TService) objectConstructorDelegate(resolver);
          return svc;
      }
      


      Adding that parameter would cause runtime error when doing a reflection call on original RegisterDelegate method. ConstructObjectThenCast method is the substitute method for the original RegisterDelegate's lambda parameter
      Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.


      Looking at the original RegisterDelegate method signature shows why:
      public static void RegisterDelegate<TService>(
           this IRegistrator registrator, Func<IResolver, TService> lambda, 
           IReuse reuse = null, FactorySetup setup = null, string named = null);
      

      The lambda delegate we want to hook on has one parameter only, IResolver only. Hence if Func<IResolver, object> objectConstructorDelegate is added to parameters of ConstructObjectThenCast, it results to the error above


      However, since we cannot add another parameter on the substitute method(ConstructObjectThenCast) to the lambda, the only way to pass the user-defined lambda to the original RegisterDelegate is to create a class instance, which is not possible on static class, hence the need for two classes. So when the original RegisterDelegate method calls our substitute method for original RegisterDelegate's lambda, we can still call the user-defined lambda in turn. The user-defined lambda is stored in a non-static class, it's a field on that class: Func<DryIoc.IResolver,object> _objectConstructorDelegate;


      ConstructObjectThenCast is the method that will cast an object to its dependency-injected type(e.g., in an interface), that's the method we will substitute to RegisterDelegate's lambda parameter. In order for that substitute method to be able to call our user-defined lambda, we will call the user-defined lamba from the class instance. this._objectConstructorDelegate is where the user-defined lambda is stored
      TService ConstructObjectThenCast<TService>(IResolver resolver)
      {
          var svc = (TService) this._objectConstructorDelegate(resolver);
          return svc;
      }
      




      Here's the complete code of the additional API. This also shows how to use DryIoc on ASP.NET MVC and WCF:
      using System;
      using System.Linq;
      using System.Web.Http;
      using System.Web.Mvc;
      using System.Web.Routing;
      
      using DryIoc;
      using AspNetMvcUseWcf.Controllers;
      
      namespace AspNetMvcUseWcf
      {
          public class MvcApplication : System.Web.HttpApplication
          {
              protected void Application_Start()
              {
                  AreaRegistration.RegisterAllAreas();
      
                  WebApiConfig.Register(GlobalConfiguration.Configuration);
                  FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                  RouteConfig.RegisterRoutes(RouteTable.Routes);
      
                  
                  ControllerBuilder.Current.SetControllerFactory(new DryIocDependencyResolver());   
              }
          }
      
          class DryIocDependencyResolver : System.Web.Mvc.DefaultControllerFactory
          {
              DryIoc.Container _container;
      
              public DryIocDependencyResolver()
              {
                  _container = new DryIoc.Container();
                  RegisterTheIocs();
              }
      
              protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
              {
                  System.Web.Mvc.IController ic = controllerType == null
                      ? null
                      : (System.Web.Mvc.IController)_container.Resolve(controllerType);
      
                  // _container.ResolvePropertiesAndFields(ic);  // uncomment this if you want to use DI on controller's properties
      
                  return ic;
              }
      
              void RegisterTheIocs()
              {
                  RegisterMvcControllers();
                  RegisterWcfServices();
              }
      
              void RegisterWcfServices()
              {
                  _container.Register<System.ServiceModel.BasicHttpBinding>(DryIoc.Reuse.Singleton, x => x.GetConstructor(new Type[] { }));
      
      
                  foreach (var contractType in typeof(TheServiceContracts.IMemberService).Assembly.GetTypes())
                  {                
                      _container.RegisterDelegate(contractType,
                          r =>
                          {
                              var binding = r.Resolve<System.ServiceModel.BasicHttpBinding>();
      
                              var svcAddress = "http://localhost:1337/" + contractType.Name.Substring(1) + ".svc";
                              var endpointAddress = new System.ServiceModel.EndpointAddress(svcAddress);
      
      
                              return ServiceModelHelper.CreateService(contractType, binding, endpointAddress);
                          }, Reuse.InResolutionScope);
      
                  }
              }
      
              void RegisterMvcControllers()
              {
                  System.Reflection.Assembly assembly = typeof(HomeController).Assembly;
      
                  foreach (var controller in assembly.GetTypes().Where(t => typeof(Controller).IsAssignableFrom(t)))
                  {
                      _container.Register(controller, DryIoc.Reuse.InResolutionScope);
                  }
              }
      
      
          } // class DryIocDependencyResolver
      
      
      
      
      
      
          public static class ResolverExtensionHelper
          {
              public static void RegisterDelegate(this DryIoc.IResolver container,
                   Type contractType, Func<DryIoc.IResolver, object> objectConstructorDelegate,
                   DryIoc.IReuse reuse = null, DryIoc.FactorySetup setup = null, string named = null)
              {
                  ResolverBuilder.Build(container, contractType, objectConstructorDelegate, reuse, setup, named);
              }
          }
      
          public class ResolverBuilder
          {
              
              Func<DryIoc.IResolver,object> _objectConstructorDelegate;
      
      
              public static void Build(DryIoc.IResolver container, Type contractType, Func<IResolver, object> objectConstructor, IReuse reuse, FactorySetup setup, string named)
              {
                  new ResolverBuilder(container, contractType, objectConstructor, reuse, setup, named);
              }
      
              ResolverBuilder(
                  DryIoc.IResolver resolver, Type contractType, Func<DryIoc.IResolver, object> objectConstructorDelegate,
                  DryIoc.IReuse reuse = null, DryIoc.FactorySetup setup = null, string named = null
                  )
              {
                  _objectConstructorDelegate = objectConstructorDelegate;
      
                  Delegate lambda;
                  {
                      System.Reflection.MethodInfo constructObjectThenCastMethodInfo = Create_ConstructObjectThenCast_MethodInfo_For_ContractType(contractType);
                      lambda = Create_ConstructObjectThenCast_Lambda_For_ContractType(this, constructObjectThenCastMethodInfo, contractType);
                  }
      
      
                  // Invoke the original RegisterDelegate<TService>            
                  {
                      // public static void RegisterDelegate<TService>(this DryIoc.IRegistrator registrator, Func<DryIoc.IResolver, TService> lambda, 
                      //                                                     DryIoc.IReuse reuse = null, DryIoc.FactorySetup setup = null, string named = null);
      
                      // obj is null, means RegisterDelegate is a static method
                      // resolver comes from _container
                      // contractType is the TService in the original _container.RegisterDelegate<TService>
                      System.Reflection.MethodInfo registerDelegateMethodInfo = typeof(DryIoc.Registrator).GetMethod("RegisterDelegate").MakeGenericMethod(contractType);
                      registerDelegateMethodInfo.Invoke(/*obj*/ null, new object[] { resolver, lambda, reuse, setup, named });
                  }
              }
      
              static System.Reflection.MethodInfo Create_ConstructObjectThenCast_MethodInfo_For_ContractType(Type contractType)
              {
      
                  System.Reflection.MethodInfo constructObjectThenCastMethodInfo =
                      // typeof(IResolver) is the resolver parameter of: TService ConstructObjectThenCast<TService>(IResolver resolver)
                     typeof(ResolverBuilder).GetMethod(
                         name: "ConstructObjectThenCast",
                         types: new[] { typeof(IResolver) },
                         bindingAttr: System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance,
                         binder: null,
                         modifiers: null
                         )
                      // contractType is the TService of ConstructObjectThenCast<TService>
                     .MakeGenericMethod(contractType);
                  return constructObjectThenCastMethodInfo;
              }
      
      
              // Create a lambda out of this class method: TService ConstructObjectThenCast<TService>(IResolver resolver)
              static Delegate Create_ConstructObjectThenCast_Lambda_For_ContractType(ResolverBuilder resolverBuilder,  System.Reflection.MethodInfo constructObjectThenCastMethodInfo, Type contractType)
              {
                  // Create a Func<IResolver,TService> delegate type
                  // This will be used as the lambda parameter on the original RegisterDelegate static method.                                          
                  Type lambdaDelegateType = typeof(Func<,>).MakeGenericType(typeof(DryIoc.IResolver), contractType);
                  // The above corresponds to this example: Func<IResolver, TheServiceContracts.IProductService>
      
      
                  // Cannot use Activator.CreateInstance on delegate type as delegates don't have constructor
                  // ConstructObjectThenCast method has a signature same as lambdaDelegateType 
                  // Create a lambda out of ConstructObjectThenCast method info
                  Delegate lambda = Delegate.CreateDelegate(lambdaDelegateType, resolverBuilder, constructObjectThenCastMethodInfo);
      
                  return lambda;
              }
      
           
              TService ConstructObjectThenCast<TService>(IResolver resolver)
              {
                  var svc = (TService) this._objectConstructorDelegate(resolver);
                  return svc;
              }
      
      
          }// class ResolverBuilder
      
      
          public static class ServiceModelHelper
          {
              public static object CreateService(
                  Type contractType,
                  System.ServiceModel.BasicHttpBinding basicHttpBinding,
                  System.ServiceModel.EndpointAddress endpointAddress
                  )
              {
                  var binding = new System.ServiceModel.BasicHttpBinding();
                  //Get the address of the service from configuration or some other mechanism - Not shown here
      
                  //dynamic factory generation
                  object factory =
                      Activator.CreateInstance(typeof(System.ServiceModel.ChannelFactory<>)
                      .MakeGenericType(contractType), binding, endpointAddress);
      
                  System.Reflection.MethodInfo createFactory = factory.GetType().GetMethod("CreateChannel", new Type[] { });
                  //now dynamic proxy generation using reflection
                  return createFactory.Invoke(factory, null);
              }
          }
          
      }//namespace
      



      Happy Coding!

      Sunday, October 19, 2014

      C# var abuse

      What happened to programming to an interface?



      You have this DLL that contains this interface and implementation:
      namespace UnitTestFriendlyDal
      {
          public interface IDomainAccess : IDisposable
          {
              object Save(object transientObject);
              IQueryable<T> Query<T>();
              T Get<T>(object id);
              T Load<T>(object id);
              void Evict<T>(object id);
          }
      
          public class DomainAccess : IDomainAccess
          {
      
              NHibernate.ISessionFactory _sessionFactory;
              NHibernate.ISession _session;
              NHibernate.ITransaction _transaction;
      
      
              public DomainAccess(NHibernate.ISessionFactory sessionFactory)
              {
                  _sessionFactory = sessionFactory;
                  _session = _sessionFactory.OpenSession();
                  _transaction = _session.BeginTransaction();
              }
      
              // IDomainAccess implementation...
              
      
      
              public Save(object transientObject)
              {
                  return _session.Save(transientObject);
              }
      
              
              IQueryable<T> Query<T>()
              {
                  return _session.Query<T>();
              }
      
      
              public T Get<T>(object id)
              {
                  return _session.Get<T>(id);
              }
      
              public T Load<T>(object id)
              {
                  return _session.Load<T>(id);
              }
      
      
      
              public void Evict<T>(object id)
              {
                  _sessionFactory.Evict(typeof(T), id);
              }
              
      
              
              // Because transaction is a cross-cutting concern. It should be automated
              void IDisposable.Dispose()
              {
                   // http://www.hibernatingrhinos.com/products/nhprof/learn/alert/donotuseimplicittransactions
                          
                  _transaction.Commit();
                  _transaction.Dispose();
                  _session.Dispose();
              }
      
      
              //... IDomainAccess implementation
          }
      }
      


      Developers will use DomainAccess directly instead:
      using (var da = new DomainAccess(_sessionFactory))
      {    
          var c = Customer.Get(domainAccess: da, id: 1);
      }
      


      So what happen now to programming to an interface principle? Prior to C# version 3, you can still convince your colleagues to use variable declaration that adheres to programming to an interface principle: IDomainAccess da = new DomainAccess(), instead of: DomainAccess da = new DomainAccess(). interface variable declaration is just one letter away from its concrete class variable declaration :-)


      Now, some developers will steadfastly refuse to type the type anymore. Code's obviousness to other developers is not given an attention, worse yet most won't care anymore if the code is not adhering to programming to an interface principle anymore


      Another problem with var, when you generate method stub using the da variable from a var declaration, Visual Studio will generate the method stub based on da's concrete class, not based on its interface:
      public static Get(DomainAccess domainAccess, int id)
      {
      }
      

      When it should ideally be interface-based instead:
      public static Customer Get(IDomainAccess domainAccess, int id) 
      {
      }
      


      What you wanted your fellow colleagues to practice:
      using (IDomainAccess da = new DomainAccess(_sessionFactory))
      {    
          var c = Customer.Get(domainAccess: da, id: 1);    
      }
      


      There's a slim chance that you can convince your colleagues who are fans of var to declare variables based on their interface

      Surely, most C# developers didn't heed this Microsoft warning:
      However, the use of var does have at least the potential to make your code more difficult to understand for other developers. For that reason, the C# documentation generally uses var only when it is required


      Another good argument against var abuse. Bradley Smith wrote:
      var encourages Hungarian Notation

      If the ommission of type names from variable declarations forces us to more carefully name our variables, it follows that variable names are more likely to describe not only their purpose, but also their type:

      var dtIndividuals = GetContacts(ContactTypes.Individuals);

      This is precisely the definition of Hungarian Notation, which is now heavily frowned upon as a practice, especially in type-safe languages like C#.


      dtIndividuals is DataTable individuals. Imagine when there was no var, variable declaration like DataTable dtIndividuals are frowned upon; but now there's var, it's ok to use Hungarian notation again?


      var is the most abused language feature


      How I wish that compilers could at least advise the developer to use the concrete class' interface instead when declaring variables


      To solve the problem above without incurring friction with var everything camp, you can make your concrete classes implement interfaces explicitly, thereby hiding the concrete class' implemented interface methods.
      public class DomainAccess : IDomainAccess
      {
      .
      .
      . 
          // Implement interfaces explicitly. This will make Save not available on DomainAccess instance
          IDomainAccess.Save(object transientObject)
          {
              return _session.Save(transientObject);
          }
      .
      .
      .
      }
      


      So when using the DomainAccess directly (via var), accessing its method will result to compile error..
      using (var da = new DomainAccess(_sessionFactory))
      {        
          da.Save(new Company{ ... }); // this will result to compile error, Save is inaccessible from concrete class DomainAccess
      }
      


      ..so that would compel the developer to program to an interface instead::
      using (IDomainAccess da = new DomainAccess(_sessionFactory))
      {       
          da.Save(new Company{ ... }); // this will compile, Save is accessible from the IDomainAccess interface
      }
      


      Problem solved, that's programming to an interface. Using EIMI as a solution to this problem still has wrinkles in it, programming to an interface can be enforced but it's still easy to accidentally use the DomainAccess concrete class directly via the var keyword, the developer shall then have to change the variable declaration to use the interface instead, wasting time


      There's a better approach, we can make the DomainAccess non-public, then just give the user an instance of IDomainAccess implementation from a factory
      // remove the public keyword
      class DomainAccess : IDomainAccess
      {
          // implement interface methods
      }
      


      When used outside of DomainAccess project, this will not compile:
      var da = new DomainAccess(_sessionFactory); // DomainAccess is not visible to other projects
      



      So to give the user an IDomainAccess object, the dev shall use this pattern instead:
      public class CompaniesController : Controller
      {
          IDomainAccessFactory _daf;
          
          public CompaniesController(IDomainAccessFactory daf)
          {
              _daf = daf;
          }
          
          public JsonResult CompanySave(CompanyDto dto)
          {
              int savedId = 0;
              // OpenDomainAccess returns IDomainAccess instead of returning DomainAccess
              using (var da = _daf.OpenDomainAccess())
              {
                  savedId = da.Save(new Company{...});            
              }                
              return Json(new { savedId = savedId });
          }        
      }
      


      DomainAccess cannot be instantiated directly anymore, it shall be built from a factory instead and return it through interface. Here's an implementation:
      namespace UnityTestFriendlyDal
      {
          public interface IDomainAccessFactory
          {
              IDomainAccess OpenDomainAccess();
          }
          
          public class DomainAccessFactory : IDomainAccessFactory
          {
              NHibernate.ISessionFactory _sessionFactory;
      
              public DomainAccessFactory(NHibernate.ISessionFactory sessionFactory)
              {
                  _sessionFactory = sessionFactory;
              }
              
              // return through DomainAccess concrete class through IDomainAccess interface
              public IDomainAccess OpenDomainAccess()
              {
                  return new DomainAccess(_sessionFactory);
              }
          }
      
          public interface IDomainAccess : IDisposable
          {
              object Save(object transientObject);
              IQueryable<T> Query<T>();
              T Get<T>(object id);
              T Load<T>(object id);
              void Evict<T>(object id);
          }
          
          // Don't make this public
          class DomainAccess : IDomainAccess
          {
              // Though you can use public/internal on method implementations (as long as you don't make the class DomainAcess public), 
              // it's advisable to use explicit interface method implementation instead
      
              // interface implementations here
          }
      }
      


      When you generate a method stub from a variable declaration using var that receives an interface, the generated method stub will naturally generates a method with a parameter of interface. You can reap the benefit of using interfaces when you can properly enforce the use of interfaces everywhere



      Good read on "To var or not to var" :

      http://shahinalborz.se/2011/01/to-var-or-not-to-var-c-implicit-variable-declaration/

      http://www.brad-smith.info/blog/archives/336

      http://weblogs.asp.net/stevewellens/can-the-c-var-keyword-be-misused

      Good read on Programming To An Interface:

      http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface/384067#384067

      http://www.codeproject.com/Articles/392516/Why-I-use-explicit-interface-implementation-as-a-d




      Happy Coding!

      Friday, October 17, 2014

      Benchmarking .NET JSON Serializers

      using System;
      using System.Collections.Generic;
      using System.Diagnostics;
      
      namespace PlayJsonSerializers
      {
          class Program
          {
              static void Main(string[] args)
              {
                  Func<object,string> netJson = o => NetJSON.NetJSON.Serialize(o);
                      
                  Func<object,string> jil = o => Jil.JSON.Serialize(o);
                  
                  Func<object, string> ssText = o => ServiceStack.Text.JsonSerializer.SerializeToString(o);
      
                  // ASP.NET Web API default JSON serializer
                  Func<object, string> jsonNet = o => Newtonsoft.Json.JsonConvert.SerializeObject(o);
      
                  var aspNetWebMvcDefaultJsonSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
                  Func<object, string> javaScriptSerializer = o => aspNetWebMvcDefaultJsonSerializer.Serialize(o);
                  // To replace ASP.NET MVC JSON serializer: http://www.ienablemuch.com/2014/10/aspnet-mvc-return-json-without-using-jsonresult.html
      
      
                  var jsSerializers = new Dictionary<string, Func<object, string>>()
                  {
                      { "NetJSON", netJson },                
                      { "Jil", jil },
                      { "ServiceStack.Text", jil },
                      { "Json.NET", jsonNet },
                      { "ASP.NET MVC Default", javaScriptSerializer}
                  };
      
      
                  Action<string,object> benchmark = (description,o) =>
                  {
                      const string netJsonReplacedWithJsonNet = "NetJSON Replaced with Json.NET";
      
                      var fallbackJsonSerializer = jsonNet;
      
                      bool isAnonymousType = o.GetType().IsAnonymousType();
      
                      Console.WriteLine(description);
                     
                      Console.WriteLine("Serialization");
                      foreach (var item in jsSerializers)
                      {
                          if (isAnonymousType && item.Key == "NetJSON")
                              fallbackJsonSerializer(o).Show(netJsonReplacedWithJsonNet);
                          else
                              item.Value(o).Show(item.Key);
                          
                      }
      
                      Console.WriteLine("Speed");
                      foreach (var item in jsSerializers)
                      {
                          if (isAnonymousType && item.Key == "NetJSON")
                              ShowTime(netJsonReplacedWithJsonNet, delegate { for (int i = 0; i < 20000; i++) fallbackJsonSerializer(o); });
                          else
                              ShowTime(item.Key, delegate { for (int i = 0; i < 20000; i++) item.Value(o); });
                      }
      
                      Console.WriteLine(new string('-',80));
                  };
      
      
                  benchmark("Object with complete properties", 
                      new Person { PersonId = 123456789, FirstName = "Linus", MiddleName = "Great", LastName = "Snoopy" });
      
                  benchmark("Object with null properties", 
                      new Person { PersonId = 123456789, FirstName = "Linus", LastName = "Snoopy" });
      
      
                  benchmark("Object with inheritance",
                      new Employee { PersonId = 123456789, FirstName = "Linus", MiddleName = "Great", LastName = "Snoopy", IsActive = true });
      
                              
                  benchmark("Anonymous object with complete properties", 
                      new { PersonId = 123456789, FirstName = "Linus", MiddleName = "Great", LastName = "Snoopy", IsActive = true });
      
      
                  benchmark("Anonymous object. Property with inheritance",
                      new { Greet = "Hello", Employee = new Employee { PersonId = 123456789, FirstName = "Linus", MiddleName = "Great", LastName = "Snoopy", IsActive = true } });
                                  
              }
      
      
              static void ShowTime(string jsSerializer, Action task)
              {
                  var sw = Stopwatch.StartNew();
      
                  task();
      
                  sw.Stop();
                  var milliseconds = (long)sw.ElapsedMilliseconds;
                  Console.WriteLine("{0, 30}: {1}", jsSerializer, milliseconds);
              }
          }
      
          public class Person
          {
              public int      PersonId    { get; set; }
              public string   FirstName   { get; set; }
              public string   MiddleName  { get; set; }
              public string   LastName    { get; set; }
          }
      
          public class Employee : Person
          {
              public bool IsActive { get; set; }
          }
      
          static class StringExtension
          {
              internal static void Show(this string s, string description = "")
              {
                  Console.WriteLine("{0, 30}: {1}", description, s);
              }
          }
      
          
          static class TypeExtension
          {
              // http://www.jefclaes.be/2011/05/checking-for-anonymous-types.html
              static internal bool IsAnonymousType(this Type type)
              {
                  Debug.Assert(type != null, "Type should not be null");
      
                  // HACK: The only way to detect anonymous types right now.
                  return Attribute.IsDefined(type, typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute), false)
                             && type.IsGenericType && type.Name.Contains("AnonymousType")
                             && (type.Name.StartsWith("<>", StringComparison.OrdinalIgnoreCase) ||
                                 type.Name.StartsWith("VB$", StringComparison.OrdinalIgnoreCase))
                             && (type.Attributes & System.Reflection.TypeAttributes.NotPublic) == System.Reflection.TypeAttributes.NotPublic;
              }
          }
      }
      


      Results:
      Object with complete properties
      Serialization
                             NetJSON: {"PersonId":123456789,"FirstName":"Linus","MiddleName":"Great","LastName":"Snoopy"}
                                 Jil: {"PersonId":123456789,"LastName":"Snoopy","MiddleName":"Great","FirstName":"Linus"}
                   ServiceStack.Text: {"PersonId":123456789,"LastName":"Snoopy","MiddleName":"Great","FirstName":"Linus"}
                            Json.NET: {"PersonId":123456789,"FirstName":"Linus","MiddleName":"Great","LastName":"Snoopy"}
                 ASP.NET MVC Default: {"PersonId":123456789,"FirstName":"Linus","MiddleName":"Great","LastName":"Snoopy"}
      Speed
                             NetJSON: 38
                                 Jil: 77
                   ServiceStack.Text: 89
                            Json.NET: 119
                 ASP.NET MVC Default: 1022
      --------------------------------------------------------------------------------
      Object with null properties
      Serialization
                             NetJSON: {"PersonId":123456789,"FirstName":"Linus","LastName":"Snoopy"}
                                 Jil: {"PersonId":123456789,"LastName":"Snoopy","MiddleName":null,"FirstName":"Linus"}
                   ServiceStack.Text: {"PersonId":123456789,"LastName":"Snoopy","MiddleName":null,"FirstName":"Linus"}
                            Json.NET: {"PersonId":123456789,"FirstName":"Linus","MiddleName":null,"LastName":"Snoopy"}
                 ASP.NET MVC Default: {"PersonId":123456789,"FirstName":"Linus","MiddleName":null,"LastName":"Snoopy"}
      Speed
                             NetJSON: 28
                                 Jil: 84
                   ServiceStack.Text: 75
                            Json.NET: 131
                 ASP.NET MVC Default: 1020
      --------------------------------------------------------------------------------
      Object with inheritance
      Serialization
                             NetJSON: {"IsActive":true,"PersonId":123456789,"FirstName":"Linus","MiddleName":"Great","LastName":"Snoopy"}
                                 Jil: {"IsActive":true}
                   ServiceStack.Text: {"IsActive":true}
                            Json.NET: {"IsActive":true,"PersonId":123456789,"FirstName":"Linus","MiddleName":"Great","LastName":"Snoopy"}
                 ASP.NET MVC Default: {"IsActive":true,"PersonId":123456789,"FirstName":"Linus","MiddleName":"Great","LastName":"Snoopy"}
      Speed
                             NetJSON: 37
                                 Jil: 53
                   ServiceStack.Text: 48
                            Json.NET: 148
                 ASP.NET MVC Default: 1307
      --------------------------------------------------------------------------------
      Anonymous object with complete properties
      Serialization
      NetJSON Replaced with Json.NET: {"PersonId":123456789,"FirstName":"Linus","MiddleName":"Great","LastName":"Snoopy","IsActive":true}
                                 Jil: {"IsActive":true,"PersonId":123456789,"LastName":"Snoopy","MiddleName":"Great","FirstName":"Linus"}
                   ServiceStack.Text: {"IsActive":true,"PersonId":123456789,"LastName":"Snoopy","MiddleName":"Great","FirstName":"Linus"}
                            Json.NET: {"PersonId":123456789,"FirstName":"Linus","MiddleName":"Great","LastName":"Snoopy","IsActive":true}
                 ASP.NET MVC Default: {"PersonId":123456789,"FirstName":"Linus","MiddleName":"Great","LastName":"Snoopy","IsActive":true}
      Speed
      NetJSON Replaced with Json.NET: 156
                                 Jil: 94
                   ServiceStack.Text: 111
                            Json.NET: 171
                 ASP.NET MVC Default: 1702
      --------------------------------------------------------------------------------
      Anonymous object. Property with inheritance
      Serialization
      NetJSON Replaced with Json.NET: {"Greet":"Hello","Employee":{"IsActive":true,"PersonId":123456789,"FirstName":"Linus","MiddleName":"Great","LastName":"Snoopy"}}
                                 Jil: {"Employee":{"IsActive":true},"Greet":"Hello"}
                   ServiceStack.Text: {"Employee":{"IsActive":true},"Greet":"Hello"}
                            Json.NET: {"Greet":"Hello","Employee":{"IsActive":true,"PersonId":123456789,"FirstName":"Linus","MiddleName":"Great","LastName":"Snoopy"}}
                 ASP.NET MVC Default: {"Greet":"Hello","Employee":{"IsActive":true,"PersonId":123456789,"FirstName":"Linus","MiddleName":"Great","LastName":"Snoopy"}}
      Speed
      NetJSON Replaced with Json.NET: 222
                                 Jil: 95
                   ServiceStack.Text: 103
                            Json.NET: 211
                 ASP.NET MVC Default: 2200
      --------------------------------------------------------------------------------
      


      Summary:
      * NetJSON is the fastest
      * Jil and ServiceStack can't serialize inherited classes
      * NetJSON doesn't serialize null propeties, good optimization

      As for replacing NetJSON with Json.NET, NetJSON can't serialize anonymous objects yet



      Happy Coding!