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
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 IDomainAccess
    {
        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 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 from var everything camp, you can develop your concrete classes to implement interfaces explicitly
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, he 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!

ASP.NET MVC - Return JSON without using JsonResult

After using ServiceStack and ASP.NET Web API, and then using ASP.NET MVC again, you'll be wanting to just return the model as-is and just forget the explicit infrastructure to return the model as JSON

public JsonResult GetTopSellingProduct(int year)
{
    using(IDataStore ds = new DataStore(_nhibernateSessionFactory))
    {
        return Json(Product.GetTopSellingProduct(ds, year), JsonRequestBehavior.AllowGet);
    }    
}


This is how we wanted to return models as JSON even in ASP.NET MVC controller:
public Product GetTopSellingProduct(int year)
{
    using(IDataStore ds = new DataStore(_nhSessionFactory))
    {
        return Product.GetTopSellingProduct(ds, year);
    }    
}


Turns out that is possible, Adam Bar noticed ASP.NET MVC can be made to return JSON object implicitly


Here's a complete code that enables ASP.NET Web API-like controller action to ASP.NET MVC. This is using NetJSON for JSON serialization, and DryIoc for IoC/DI needs. DryIoc is the fastest IoC/DI and NetJSON is the fastest JSON serializer

using Erp.Controllers;

using DryIoc; // http://www.palmmedia.de/blog/2011/8/30/ioc-container-benchmark-performance-comparison
using NJ = NetJSON; // http://theburningmonk.com/2014/08/json-serializers-benchmarks-updated-2/

using System;

using System.Linq;



namespace Erp
{
    public class MvcApplication : System.Web.HttpApplication
    {
        DryIocDependencyResolver _ioc = new DryIocDependencyResolver(); // Customized DefaultControllerFactory
        
        protected void Application_Start()
        {
            System.Web.Mvc.AreaRegistration.RegisterAllAreas();

            
            FilterConfig.RegisterGlobalFilters(System.Web.Mvc.GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(System.Web.Routing.RouteTable.Routes);

                        
            System.Web.Mvc.ControllerBuilder.Current.SetControllerFactory(_ioc);
            
        }
    
    }
       

    class DryIocDependencyResolver : System.Web.Mvc.DefaultControllerFactory
    {
        internal DryIoc.Container _container;

        public DryIocDependencyResolver()
        {
            _container = new DryIoc.Container();
            RegisterTheIocs();
        }


        protected override System.Web.Mvc.IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
        {
            System.Web.Mvc.IController ic = controllerType == null
                ? null
                : (System.Web.Mvc.IController)_container.Resolve(controllerType);


            // _container.ResolvePropertiesAndFields(controller);  // uncomment this if you want to use DI on controller's properties

            var mvcController = ic as System.Web.Mvc.Controller;

            if (mvcController != null)
                mvcController.ActionInvoker = new SimulateWebApi();

            return mvcController;
        }


        class SimulateWebApi : System.Web.Mvc.ControllerActionInvoker
        {
            const string JsonContentType = "application/json";

            protected override System.Web.Mvc.ActionResult CreateActionResult(
                System.Web.Mvc.ControllerContext controllerContext, System.Web.Mvc.ActionDescriptor actionDescriptor, object actionReturnValue)
            {
                if (actionReturnValue == null)
                    return new System.Web.Mvc.EmptyResult();

                return (actionReturnValue as System.Web.Mvc.ActionResult) ?? new System.Web.Mvc.ContentResult()
                {
                    ContentType = JsonContentType,
                    Content = NJ.NetJSON.Serialize (actionReturnValue)
                };
            }
        }


        void RegisterTheIocs()
        {            
            System.Reflection.Assembly assembly = typeof(HomeController).Assembly;

            foreach (var controller in assembly.GetTypes().Where(t => typeof(System.Web.Mvc.Controller).IsAssignableFrom(t)))
            {
                _container.Register(controller, DryIoc.Reuse.InResolutionScope);                
            }
           

            _container.Register(typeof(Elmah.Mvc.ElmahController), DryIoc.Reuse.InResolutionScope);

            // http://ayende.com/blog/153701/ask-ayende-life-without-repositories-are-they-worth-living
            // http://www.ienablemuch.com/2014/10/typical-nhibernate-sessionfactory-auto-mapping.html
            _container.RegisterDelegate<NHibernate.ISessionFactory>(x => Erp.DomainMapping.Mapper.SessionFactory, DryIoc.Reuse.Singleton);            
        }

    }//DefaultControllerFactory

    

}//namespace



JSON Serializers benchmark: http://www.ienablemuch.com/2014/10/benchmarking-net-json-serializers.html


Happy Coding!