After the install of an IoC (Inversion of Control) container, some tweaks are needed to make it work. In this case, I'll use Ninject. In the NinjectWebCommon file, that is located in the App_Start folder, substitute the CreateKernel method with:
private static IKernel CreateKernel()
{
// Create the kernel with the interface to concrete bindings
var kernel = RegisterServices();
try
{
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}
And the RegisterServices method with:
private static StandardKernel RegisterServices()
{
Container container = new Container();
// encapsulate the interface to concrete bindings in another class or even in another layer
StandardKernel kernel = container.GetServices();
return kernel;
}
Create a new class to to the binding that in this case is called Container:
public class Container
{
public StandardKernel GetServices()
{
// It is good practice to create a derived class of NinjectModule to organize the binding by concerns. In this case one for the repository, one for service and one for app service bindings
return new StandardKernel(new NinjectRepositoryModule(),
new NinjectServiceModule(),
new NinjectAppServiceModule());
}
}
Finally in each derived NinjectModule class modify the bindings overloading the Load method like:
public class NinjectRepositoryModule: NinjectModule
{
public override void Load()
{
// When we need a generic IRepositoryBase<> to bind to a generic RepositoryBase<>
// The typeof keyword is used because the target method is generic
Bind(typeof (IRepositoryBase<>)).To(typeof (RepositoryBase<>));
// When we need a IUnitOfWorkbind to UnitOfWork concrete class that is a singleton
Bind<IUnitOfWork>().To<UnitOfWork>().InSingletonScope();
}
}
Another example of derived NinjectModule:
public class NinjectServiceModule :NinjectModule
{
public override void Load()
{
// When we need a IBenefitService to BenefitService concrete class
Bind<IBenefitService>().To<BenefitService>();
// When we need a ICategoryService to CategoryService concrete class
Bind<ICategoryService>().To<CategoryService>();
// When we need a IConditionService to ConditionService concrete class
Bind<IConditionService>().To<ConditionService>();
}
}