capsule.adrianhesketh.com
Migrating from Ninject to Simple Injector
OK, so it's time to part ways with Ninject. It's too slow [0], and it doesn't want to change [1].
Ninject was fast enough at first, but as apps get bigger, its performance and CPU cost get too high.
Simple Injector has a near-parity feature set (support for MVC filters isn't quite as strong), great documentation and excellent performance.
// Ninject
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind().To();
// Singleton
kernel.Bind().ToMethod(c => LogManager.GetLogger(typeof(ProjectService))).InSingletonScope();
// WCF Scope
// Done by default in Ninject when you use the WCF package.
kernel.Bind().To();
kernel.Bind().To();
return kernel;
}
// Simple Injector
private static void Start()
{
// Create the container as usual.
var container = new Container();
// Register your types.
// Singleton.
container.RegisterSingle(() => LogManager.GetLogger(typeof(ProjectService)));
// WCF Service Scope. This is different to Ninject, because using this Lifecycle in
// Simple Injector will result in only a single concrete object being created per WCF
// operation whereas Ninject can create multiple objects, but scoped to the WCF operation.
container.RegisterPerWcfOperation();
// Transient Scope.
container.Register();
// Register the container to the SimpleInjectorServiceHostFactory.
SimpleInjectorServiceHostFactory.SetContainer(container);
}
Migrating the setup is also pretty straightforward.
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(Service.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(Service.App_Start.NinjectWebCommon), "Stop")]
// Once it's building, rename the class away from Ninject.
public static class NinjectWebCommon
{
// -- Ninject
// private static readonly Bootstrapper bootstrapper = new Bootstrapper();
public static void Start()
{
// -- Ninject
/*
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
*/
// ++ Simple Injector
CreateContainer();
}
public static void Stop()
{
// -- Ninject.
// bootstrapper.ShutDown();
}
// -- Ninject
/*
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind().To();
RegisterServices(kernel);
return kernel;
}
private static void RegisterServices(IKernel kernel)
{
kernel.Bind().ToMethod(c => LogManager.GetLogger(typeof(NinjectWebCommon)));
kernel.Bind().To();
}
*/
// ++ Simple Injector
private static Container CreateContainer()
{
// Create the container as usual.
var container = new Container();
RegisterServices(container);
// Setup MVC.
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
container.RegisterMvcIntegratedFilterProvider();
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
// Setup WebApi.
container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
// Register filters (if you've used them).
RegisterGlobalFilters(GlobalFilters.Filters, container);
RegisterWebApiFilters(GlobalConfiguration.Configuration.Filters, container);
// Setup WCF.
SimpleInjectorServiceHostFactory.SetContainer(container);
return container;
}
private static void RegisterServices(Container container)
{
container.RegisterSingle(() => LogManager.GetLogger(typeof(NinjectWebCommon)));
container.Register();
}
public static void RegisterGlobalFilters(GlobalFilterCollection filters, Container container)
{
filters.Add(container.GetInstance());
}
private static void RegisterWebApiFilters(System.Web.Http.Filters.HttpFilterCollection httpFilterCollection, Container container)
{
}
}
Hope it helps someone else...