IoC with Ninject
I am developing an application using IoC and Ninject for dependency injection, and I ran into the following problem:
When uploading my application to the server I got the following error:
Could anyone help me with how to resolve this error?
IoC Method.Install
public static void Install()
{
DILoader.Install(
(tInterface, tClass) => IoC.Register(tInterface, tClass),
(tInterface, tClass) => IoC.RegisterInSingletonScope(tInterface, tClass),
(tInterface, tClass) => IoC.RegisterInThreadScope(tInterface, tClass)
);
}
This is where I load the assemblies
public static void LoadAssemblies()
{
var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
loadedAssemblies
.SelectMany(x => x.GetReferencedAssemblies())
.Distinct()
.Where(y => loadedAssemblies.Any((a) => a.FullName == y.FullName) == false)
.ToList()
.ForEach(x => loadedAssemblies.Add(AppDomain.CurrentDomain.Load(x)));
}
Here's where I call these methods
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
LoadAssemblies();
IoC.Install();
}
Method where I register os binds
public class NinjectIoCContainer : IIocContainer
{
private IKernel kernel;
private IKernel Kernel
{
get
{
if (kernel == null) {
kernel = new StandardKernel();
}
return kernel;
}
}
public void Register(Type tInterface, Type tClass)
{
Kernel.Bind(tInterface).To(tClass);
}
public void RegisterInSingletonScope(Type tInterface, Type tClass)
{
Kernel.Bind(tInterface).To(tClass).InSingletonScope();
}
public void RegisterInThreadScope(Type tInterface, Type tClass)
{
Kernel.Bind(tInterface).To(tClass).InThreadScope();
}
public TInterface Resolve<TInterface>()
{
return Kernel.Get<TInterface>();
}
}
}
To bind it takes the classes that have the attribute as the example below
[InstanceIoC]
public class UCManterUsuario : IManterManterUsuario
{
2 answers
Using the annotation [assembly]
you can configure the method that will be executed when the container IoC is started and finished.
With this it is not necessary to configure the global .asax to initialize the dependency injection container .
App_Start\NinjectWebCommon.cs
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(NinjectWebCommon), "Start")]
[assembly:WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(NinjectWebCommon), "Stop")]
namespace Aplicacao
{
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
public static void Stop()
{
bootstrapper.ShutDown();
}
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
try
{
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
LoadAssemblies();
IoC.Install();
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}
}
}
The problem is that I was mistaken in the way IoC and Ninject work,
The IoC where it loads the assemblies needs to run only once in the application lifecycle, whereas Ninject it needs to run every time the application is opened.
Completing the solution is below:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
LoadAssemblies();
}
protected void Session_Start()
{
IoC.Install();
}