Ioc with Ninject

Asked

Viewed 570 times

1

I am developing an application using Ioc and Ninject for dependency injection, and came across the following problem:

When uploading my application to the server I got the following error:

Tela de erro

Someone could help me in how to solve this mistake?

Ioc.Install method

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 carry 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)));
    }

This is 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();
    }

Way where I register the 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
    {
  • Ninject could not find any type associated with the interface IManterUsuario and being the same interface, it cannot create an instance to inject without an association being provided. You could post your code where you configure Ninject associations?

  • Put your code (where you create the kernel and where you register dependencies) so we can help.

  • I added more details!

  • The code snippet where you set up the Ninject bindings does not appear yet. You must have some method similar to this: public static void RegisterServices(IKernel kernel) { kernel.Bind<IManterUsuario>().To<ImplemetaManterUsuario>(); }

  • I have never used this Automatic loading. Apparently this implementation is failing to detect the attribution InstanceIoC. I would do a test to find out if it works by setting it in the method Install(): IoC.Register(typeof(IManterUsuario), typeof(UCManterUsuario ));

2 answers

2


Using the annotation [assembly] you can configure the method that will be executed when started and finished the ioc container.

No need to configure the Global.asax to initialize the container dependency injection.

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;
            }
         }
    } 
}

0

The problem is I was wrong in the way Ioc and Ninject work,

The Ioc where it loads the assemblies needs to run only once in the application lifecycle, while the Ninject it needs to run every time the application is opened.

Concluding 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();

    }
  • Still n is solved, the application is intermittent...heeeelp-Mee

Browser other questions tagged

You are not signed in. Login or sign up in order to post.