renchan
renchan

Reputation: 519

Using Ninject in two projects in one solution, a cyclical dependency exception

I'm using Ninject in two projects in the same solution. In MVC with Views and Web.API projects. But I'm having the following exception from Web API NinjectWebCommon.cs when trying to run both project at one time -

Error activating ModelValidatorProvider using binding from ModelValidatorProvider to NinjectDefaultModelValidatorProvider A cyclical dependency was detected between the constructors of two services.

But if I run only Web API project, I don't encounter the above mentioned exception. I have NinjectWebCommon.cs file in both projects.

In Web API -

public static void Start() //The method looks the same for MVC Project
{
    DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
    DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
    bootstrapper.Initialize(CreateKernel); 
}

private static IKernel CreateKernel()
{
    var kernel = new StandardKernel();
    try
    {
        kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();           

        GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);    
        RegisterServices(kernel);
        return kernel;
     }
     catch
     {
        kernel.Dispose();
        throw;
     }
}        
private static void RegisterServices(IKernel kernel)
{
    WebIoC.RegisterServices(kernel);
}

And MVC project -

private static IKernel CreateKernel()
{
    var kernel = new StandardKernel();
       try
       {
           kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
           kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();               

           RegisterServices(kernel);
           RegisterServiceLocator(kernel);

           return kernel;
        }
        catch
        {
            kernel.Dispose();
            throw;
        }
}

private static void RegisterServiceLocator(StandardKernel kernel)
{
    var locator = new NinjectServiceLocator(kernel);

    ServiceLocator.SetLocatorProvider(() => locator);
}

private static void RegisterServices(IKernel kernel)
{
    kernel.Bind<IFormsAuthenticationService>().To<FormsAuthenticationService>();
    kernel.Bind<IAdMembershService>().To<ActiveDirectoryMembershipService>();
    kernel.Bind<IFacebookAuthenticationService>().To<FacebookAuthenticationService>();            
}

I'm encountering this exception in bootstrapper.Initialize(CreateKernel); in Start() method. Has anyone encountered the same issue?

Update: I'm also using the following code for startup in both projects, if it matters.

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(Path.to.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(Path.to.NinjectWebCommon), "Stop")]

Upvotes: 1

Views: 1690

Answers (1)

BatteryBackupUnit
BatteryBackupUnit

Reputation: 13243

This has happened to others before, see Ninject Issue 131.

Arindamat came up with the following fix:

_kernel
    .Bind<DefaultModelValidatorProviders>()
    .ToConstant(new DefaultModelValidatorProviders(
         config.Services.GetServices(
             typeof (ModelValidatorProvider))
         .Cast<ModelValidatorProvider>()));

which gets rid of the cyclic dependency.

However, the root cause is usually a botched up installation of ninject. This answer shows how to fix it.

Upvotes: 4

Related Questions