NinjectDependencyResolver échoue à lier ModelValidatorProvider

je développe un ASP.NET Api web 2.2 avec C#, .net Framework 4.5.1.

après avoir mis à jour mon site web.Api pour Ninject 3.2.0, j'obtiens cette erreur:

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

Activation path:
  3) Injection of dependency ModelValidatorProvider into parameter defaultModelValidatorProviders of constructor of type DefaultModelValidatorProviders
  2) Injection of dependency DefaultModelValidatorProviders into parameter defaultModelValidatorProviders of constructor of type NinjectDefaultModelValidatorProvider
  1) Request for ModelValidatorProvider

Suggestions:
  1) Ensure that you have not declared a dependency for ModelValidatorProvider on any implementations of the service.
  2) Consider combining the services into a single one to remove the cycle.
  3) Use property injection instead of constructor injection, and implement IInitializable
     if you need initialization logic to be run after property values have been injected.

j'obtiens l'exception de NinjectWebCommon:

public static class NinjectWebCommon 
{
    private static readonly Bootstrapper bootstrapper = new Bootstrapper();

    /// <summary>
    /// Starts the application
    /// </summary>
    public static void Start() 
    {
        DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
        DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
        bootstrapper.Initialize(CreateKernel);
    }

    /// <summary>
    /// Stops the application.
    /// </summary>
    public static void Stop()
    {
        bootstrapper.ShutDown();
    }

    /// <summary>
    /// Creates the kernel that will manage your application.
    /// </summary>
    /// <returns>The created kernel.</returns>
    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);
            return kernel;
        }
        catch
        {
            kernel.Dispose();
            throw;
        }
    }

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel)
    {
        var containerConfigurator = new NinjectConfigurator();
        containerConfigurator.Configure(kernel);
    }        
}

NinjectDependencyResolver catégorie:

using Ninject;
using System;
using System.Collections.Generic;
using System.Web.Http.Dependencies;

namespace Matt.SocialNetwork.Web.Common
{
    public class NinjectDependencyResolver : IDependencyResolver
    {
        private readonly IKernel _container;

        public IKernel Container
        {
            get { return _container; }
        }

        public NinjectDependencyResolver(IKernel container)
        {
            _container = container;
        }

        public object GetService(Type serviceType)
        {
            return _container.TryGet(serviceType);
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            return _container.GetAll(serviceType);
        }

        public IDependencyScope BeginScope()
        {
            return this;
        }

        public void Dispose()
        {
            // noop
        }
    }
}

NinjectConfigurator catégorie:

public class NinjectConfigurator
{
    public void Configure(IKernel container)
    {
        // Add all bindings/dependencies
        AddBindings(container);

        // Use the container and our NinjectDependencyResolver as
        // application's resolver
        var resolver = new NinjectDependencyResolver(container);
        GlobalConfiguration.Configuration.DependencyResolver = resolver;
    }

    // Omitted for brevity.
}

la chose étrange est qu'il compile et fonctionne parfaitement, mais après mise à jour il ne fonctionne pas.

j'ai changé ce public class NinjectDependencyResolver : IDependencyResolver, System.Web.Mvc.IDependencyResolver mais il reste ne fonctionne pas.

une idée?

UPDATE

Débogage je vois que l'exception est levée dans NinjectDependencyResolver ici:

public IEnumerable<object> GetServices(Type serviceType)
{
    return _container.GetAll(serviceType);
}

il court deux fois. Premier serviceTypeIFilterProvider et la deuxième fois serviceTypeModelValidatorProvider, et après que je reçois l'exception.

ce sont les Ninject paquets que j'utilise:

<package id="Ninject" version="3.2.2.0" targetFramework="net451" />
<package id="Ninject.MVC5" version="3.2.1.0" targetFramework="net45" />
<package id="Ninject.Web.Common" version="3.2.3.0" targetFramework="net451" />
<package id="Ninject.Web.Common.WebHost" version="3.2.3.0" targetFramework="net451" />
<package id="Ninject.Web.WebApi" version="3.2.2.0" targetFramework="net451" />

la version précédente pour ces assemblages étaient les suivants:

<package id="Ninject" version="3.2.2.0" targetFramework="net45" />
<package id="Ninject.MVC5" version="3.2.1.0" targetFramework="net45" />
<package id="Ninject.Web.Common" version="3.2.2.0" targetFramework="net451" />
<package id="Ninject.Web.Common.WebHost" version="3.2.0.0" targetFramework="net45" />
<package id="Ninject.Web.WebApi" version="3.2.0.0" targetFramework="net451" />

SECOND UPDATE

j'ai trouvé que le problème est dans cette classe:

public static class WebContainerManager
{
    public static IKernel GetContainer()
    {
        var resolver = GlobalConfiguration.Configuration.DependencyResolver as NinjectDependencyResolver;
        if (resolver != null)
        {
            return resolver.Container;
        }

        throw new InvalidOperationException("NinjectDependencyResolver not being used as the MVC dependency resolver");
    }

    public static T Get<T>()
    {
        return GetContainer().Get<T>();
    }
}

j'ai mis Dependency Resolver ici:

public class NinjectConfigurator
{
    /// <summary>
    /// Entry method used by caller to configure the given 
    /// container with all of this application's 
    /// dependencies. Also configures the container as this
    /// application's dependency resolver.
    /// </summary>
    public void Configure(IKernel container)
    {
        // Add all bindings/dependencies
        AddBindings(container);

        // Use the container and our NinjectDependencyResolver as
        // application's resolver
        var resolver = new NinjectDependencyResolver(container);
        GlobalConfiguration.Configuration.DependencyResolver = resolver;
    }

Et j'utilise WebContainerManager dans une classe qui hérite de ExceptionFilterAttribute:

public class UnhandledExceptionFilter : ExceptionFilterAttribute
{
    private readonly IExceptionLogHelper excepLogHelper;

    public UnhandledExceptionFilter()
        : this(WebContainerManager.Get<IExceptionLogHelper>()) {}

    public UnhandledExceptionFilter(IExceptionLogHelper exceptionLogHelper)
    {
        this.excepLogHelper = exceptionLogHelper;
    }

    public override void OnException(HttpActionExecutedContext actionExecutedContext)
    {
        this.excepLogHelper.LogException(actionExecutedContext);
    }
}

Donc, si j'ai supprimer WebContainerManager Je ne comprends pas ce cycle.

24
demandé sur Jørn Schou-Rode 2014-10-11 11:29:43
la source

6 ответов

j'avais toutes sortes de problèmes avec L'initialisation de WebApi2 et Ninject après la mise à jour des paquets Ninject (même la désinstallation et la suppression des anciens paquets).

spécifiquement dans votre cas, je supprimerais ces lignes de code:

// Use the container and our NinjectDependencyResolver as
// application's resolver
var resolver = new NinjectDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = resolver;

comme ils sont probablement la cause de l'erreur (le NinjectWebCommon.les bibliothèques cs et Ninject traitent de l'initialisation du résolveur de dépendances maintenant).


Pour les autres qui ont suivi une semblable chemin de mise à niveau pour moi. Ce qui a fonctionné pour moi était le suivant:

  • supprimez l'ancien code D'initialisation du navigateur DependencyResolver (pour moi, cela provoquait l'erreur spécifique que vous mentionnez comme dans les versions précédentes de Ninject/WebApi2, en mettant ces lignes dans le WebApiConfig.la méthode cs Register () est la façon dont vous avez initialisé le résolveur de dépendances...ce n'est plus le cas):

    var kernel = new StandardKernel();
    config.DependencyResolver = new NinjectDependencyResolver(kernel);
    
  • installez le Ninject.Web.WebApi.Hébergeur paquet. Cette installation le NinjectWebCommon.cs fichier. Pour moi, le simple fait de la Ninject.Web.WebApi et c'est les dépendances n'ont pas créé ce fichier.

Mes installé et fonctionne Ninject Paquets de référence:

<package id="Ninject" version="3.2.2.0" targetFramework="net452" />
<package id="Ninject.Web.Common" version="3.2.3.0" targetFramework="net452" />
<package id="Ninject.Web.Common.WebHost" version="3.2.0.0" targetFramework="net452" />
<package id="Ninject.Web.WebApi" version="3.2.3.0" targetFramework="net452" />
<package id="Ninject.Web.WebApi.WebHost" version="3.2.3.0" targetFramework="net452" />
13
répondu mips 2014-12-10 14:07:09
la source

assurez-vous que tout ancien Ninject ou Ninject.Web.Common.* les dlls ne sont pas présents dans votre dossier bin.

j'ai eu le même problème dans ma solution après avoir désinstallé Ninject.Web.Common, Ninject.Web.Common.WebHost,Ninject.Web.WebApi et Ninject.MVC5 à partir de Nuget et installé WebApiContrib.IoC.Ninject afin d'utiliser GlobalConfiguration.Configuration.DependencyResolver comme dans votre exemple. J'ai gardé la version de Ninject que j'avais déjà installé (qui était en effet 3.2.2).

l'erreur n'est pas apparue lorsque j'ai fait mes premiers changements. Cependant, après être passé de quelques branches de git à mon travail actuel, j'ai vu l'erreur. Le code qui avait fonctionné correctement la semaine dernière lançait maintenant la même erreur exacte.

Il semble que mon dossier bin a des références à l'ancien Ninject.* paquets que j'avais retirés. Après avoir supprimé ces fichiers, mon projet a fonctionné comme prévu.

6
répondu Ben Bailey 2016-07-05 19:27:46
la source

la dépendance cyclique se situe entre les classes "NinjectDefaultModelValidatorProvider" et "Defaultmodelvalidatorprovider".Ajoutez simplement une liaison pour "Defaultmodelvalidatorprovidators" sur votre démarrage comme ci-dessous:

_kernel.Bind<DefaultModelValidatorProviders>().ToConstant(new DefaultModelValidatorProviders(config.Services.GetServices(typeof (ModelValidatorProvider)).Cast<ModelValidatorProvider>()));
2
répondu Arindam 2015-09-14 18:26:21
la source

dans mon cas, cela fonctionnait très bien dans le contexte D'Owin Selfhost, mais pas lorsqu'il était hébergé dans IIS. Ma solution était de supprimer tous les assemblages liés à Ninject des paquets nuget sauf Ninject lui-même.

puis j'ai écrit ma propre classe DependencyResolver, n'hésitez pas à laisser des améliorations dans les commentaires.

public class NinjectDepsolver : IDependencyResolver
{
    private IKernel _kernel;

    public NinjectDepsolver(IKernel kernel)
    {
        _kernel = kernel;
    }

    public void Dispose()
    {
        _kernel = null;
    }

    public object GetService(Type serviceType) => _kernel.TryGet(serviceType);

    public IEnumerable<object> GetServices(Type serviceType) => _kernel.GetAll(serviceType).ToArray();

    public IDependencyScope BeginScope() => new DepScope(this);

    class DepScope : IDependencyScope
    {
        private NinjectDepsolver _depsolver;

        public DepScope(NinjectDepsolver depsolver)
        {
            _depsolver = depsolver;
        }

        public void Dispose()
        {
            _depsolver = null;
        }

        public object GetService(Type serviceType) => _depsolver.GetService(serviceType);

        public IEnumerable<object> GetServices(Type serviceType) => _depsolver.GetServices(serviceType);
    }
}

et ensuite dans votre méthode de Configuration Owin:

var kernel = new StandardKernel();
kernel.Load(<your module classes>);
var httpConfig = new HttpConfiguration();
var httpConfig.DependencyResolver = new NinjectDepsolver(kernel);
var httpConfig.MapHttpAttributeRoutes();

app.UseWebApi(httpConfig);
1
répondu Arnold Pistorius 2017-06-14 10:29:13
la source

C'est ce qui a fonctionné pour moi.

uninstall-package Ninject.Web.WebApi.WebHost

la commande ci-dessus a désinstallé la version 'Ninject.Web.WebApi.Hébergeur 3.2.4.0 " et l'erreur a disparu!!

juste reconfirmer, j'ai installé le même paquet en utilisant la commande

install-package Ninject.Web.WebApi.WebHost

et la commande a installé le paquet 'Ninject.Web.WebApi.Hébergeur 3.2.4.0 " et l'erreur est réapparu.

0
répondu VivekDev 2017-07-06 09:26:07
la source
var _surveyBusiness = _kernel.Get<ISurveyBusiness>();
_surveyBusiness.SomeFunc(user.CompanyId, user.UserId);

Cela fonctionne aussi.

0
répondu Bhanu Bhanot 2018-06-14 08:57:25
la source

Autres questions sur