Error “Más de un enlaces de juego están disponibles” cuando se utiliza Ninject.Web.Mvc 2.0 y ASP.NET MVC 1.0

StackOverflow https://stackoverflow.com/questions/2423862

  •  19-09-2019
  •  | 
  •  

Pregunta

Recientemente he cambiado a la liberación de Ninject 2.0 y empecé a recibir el siguiente error:

Error occured: Error activating SomeController
More than one matching bindings are available.
Activation path:
  1) Request for SomeController

Suggestions:
  1) Ensure that you have defined a binding for SomeController only once.

Sin embargo, soy incapaz de encontrar cierta ruta de reproducción. A veces se produce, a veces no lo hace. Estoy usando NinjectHttpApplication para inyección controladores automáticos. Controladores se definen en el montaje separado:

public class App : NinjectHttpApplication
{
    protected override IKernel CreateKernel()
    {
        INinjectModule[] modules = new INinjectModule[] {
            new MiscModule(),
            new ProvidersModule(),
            new RepositoryModule(),
            new ServiceModule()
        };

        return new StandardKernel(modules);
    }

    protected override void OnApplicationStarted()
    {
        RegisterRoutes(RouteTable.Routes);
        RegisterAllControllersIn("Sample.Mvc");
        base.OnApplicationStarted();
    }

    /* ............. */

}

Tal vez alguien está familiarizado con este error.

Cualquier consejo?

¿Fue útil?

Solución

Finalmente imaginé este problema recientemente. Al parecer, la función NinjectHttpApplication.RegisterAllControllersIn () no hace todos los enlaces adecuados necesarios. Se une sus implementaciones de controladores concretas a las solicitudes IController. Por ejemplo, si usted tiene una clase controlador llamado SampleMvcController, que hereda de System.Web.Mvc.Controller. Se haría lo siguiente nombrado vinculante durante el inicio de la aplicación:

kernel.Bind<IController>().To(SampleMvcController).InTransientScope().Named("SampleMvc");

Pero cuando la depuración de la NinjectControllerFactory, me parece que la solicitud se están realizando para la Ninject Kernel para devolver un objeto de la clase "SampleMvcController", no para una aplicación concreta de IController, mediante la unión con nombre de "SampleMvc".

Debido a esto, cuando la primera solicitud web que consiste en la SampleMvcController se hace, se crea una unión de SampleMvcController a sí mismo. Esto no es de subprocesos sin embargo. Así que si usted tiene varias peticiones web se están realizando a la vez, los enlaces potencialmente pueden ocurrir más de una vez, y ahora lo que queda es este error por tener varios enlaces para el SampleMvcController.

Esto se puede comprobar mediante la actualización rápidamente una URL MVC, justo después de la causa de su aplicación web para reiniciar.

La solución:

La forma más sencilla de solucionar este problema es crear una nueva NinjectModule para sus enlaces de controlador, y para cargar este módulo durante el inicio de la aplicación. Dentro de este módulo, se auto ates cada uno de los controladores definidos, así:

class ControllerModule : StandardModule {
      public override Load() {
        Bind<SampleMvcController>().ToSelf();
        Bind<AnotherMvcController>().ToSelf();
      }
    }

Pero si no te importa cambiar el código fuente Ninject, puede modificar la función RegisterAllControllersIn () para obligar a uno mismo cada controlador que se encuentra.

Otros consejos

He estado tratando con este problema durante meses. He intentado tantas opciones pero era incapaz de llegar a una solución. Yo sabía que era un problema de roscado, ya que sólo se produciría cuando había una carga pesada en mi sitio. Hace poco, un error se informó y se fija en el código fuente ninject que resuelve este problema.

Esta es una referencia al tema . Se fija en la acumulación 2.1.0.70 de la fuente de Ninject. El cambio de clave estaba en KernelBase.cs mediante la eliminación de la línea

context.Plan = planner.GetPlan(service);

y su sustitución por

lock (planner)
{
    context.Plan = planner.GetPlan(service);
}

Para utilizar esta nueva construcción con MVC que se necesita para obtener la última versión de Ninject continuación, obtener la última versión de ninject.web.mvc . Construir ninject.web.mvc con la nueva construcción Ninject.

He estado usando esta nueva construcción cerca de una semana con una carga pesada y no hay problemas. Que es el más largo que ha pasado sin ningún problema por lo que yo consideraría que se trata de una solución.

¿Estás seguro de que realmente está creando un único completamente nuevo Kernel desde cero en su OnApplicationStarted cada vez que se invoca? Si no estás y en realidad se está creando una vez, pero potencialmente ejecutar el bit de registro dos veces. Recuerde que no está garantizado que sólo tenga una instancia de una clase App siempre dentro de un dominio de aplicación dada.

Mi respuesta fue un poco más evidente.

Me había declarado la unión de uno de mis reguladores más de una vez durante refactor de mi código.

He añadido esto a mi archivo global.ascx.cs:

        public void RegisterAllControllersInFix(Assembly assembly)
    {
        RegisterAllControllersInFix(assembly, GetControllerName);
    }

    public void RegisterAllControllersInFix(Assembly assembly, Func<Type, string> namingConvention)
    {
        foreach (Type type in assembly.GetExportedTypes().Where(IsController))
            Kernel.Bind(type).ToSelf();
    }

    private static bool IsController(Type type)
    {
        return typeof(IController).IsAssignableFrom(type) && type.IsPublic && !type.IsAbstract && !type.IsInterface;
    }

    private static string GetControllerName(Type type)
    {
        string name = type.Name.ToLowerInvariant();

        if (name.EndsWith("controller"))
            name = name.Substring(0, name.IndexOf("controller"));

        return name;
    }

A continuación, llamada de mi método OnApplicationStarted () de la siguiente manera:

        RegisterAllControllersIn(Assembly.GetExecutingAssembly());
        RegisterAllControllersInFix(Assembly.GetExecutingAssembly());

difícil saber si esto esté arreglado él sin embargo, porque es muy intermitente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top