Ошибка & ldquo; Доступно несколько совпадающих привязок & rdquo; при использовании Ninject.Web.Mvc 2.0 и ASP.NET MVC 1.0

У меня была аналогичная проблема, и выяснилось, что вся проблема такого характера может быть решена следующим образом:

  1. дает всем вашим элементам стиль.
  2. дает выбранный вами item style.
  3. дает следующие элементы стиль с использованием + или ~.

, и таким образом вы сможете стилизовать свои текущие предыдущие элементы (все элементы переопределены текущими и следующими элементами) и ваши следующие элементы.

пример:

/* all items (will be styled as previous) */
li {
  color: blue;
}

/* the item i want to distinguish */
li.milk {
  color: red;
}

/* next items */
li ~ li  {
  color: green;
}


<ul>
  <li>Tea</li>
  <li class="milk">Milk</li>
  <li>Juice</li>
  <li>others</li>
</ul>

Надеюсь, что это кому-то поможет.

30
задан Charlino 28 April 2010 в 23:59
поделиться

3 ответа

Недавно я наконец понял эту проблему. По-видимому, функция NinjectHttpApplication.RegisterAllControllersIn () не выполняет все необходимые привязки. Он связывает ваши конкретные реализации контроллера с запросами IController. Например, если у вас есть класс контроллера с именем SampleMvcController, который наследуется от System.Web.Mvc.Controller. Во время запуска приложения он будет выполнять следующую именованную привязку:

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

Но при отладке NinjectControllerFactory я обнаружил, что ядро ​​Ninject запрашивает возврат объекта для класса «SampleMvcController», а не для конкретной реализации IController, используя именованную привязку SampleMvc.

Из-за этого, когда делается первый веб-запрос, который включает SampleMvcController, он создает привязку SampleMvcController к самому себе. Однако это не является потокобезопасным. Поэтому, если у вас одновременно выполняется несколько веб-запросов, привязки могут произойти более одного раза, и теперь вы остаетесь с этой ошибкой из-за наличия нескольких привязок для SampleMvcController.

Вы можете проверить это, быстро обновив URL-адрес MVC сразу после перезапуска веб-приложения.

Исправление:

Самый простой способ решить эту проблему - создать новый NinjectModule для привязок вашего контроллера и загрузить этот модуль во время запуска приложения.В этом модуле вы самостоятельно связываете каждый из ваших определенных контроллеров, например:

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

Но если вы не против изменить исходный код Ninject, вы можете изменить функцию RegisterAllControllersIn (), чтобы самостоятельно связывать каждый обнаруженный контроллер.

23
ответ дан 28 November 2019 в 00:10
поделиться

Вы уверены, что действительно создаете одно полностью новое ядро ​​ с нуля в своем OnApplicationStarted каждый раз вызывается? Если это не так, и вы фактически создаете его один раз, но потенциально запускаете регистрационный бит дважды. Помните, что вам не гарантируется, что когда-либо будет создан только один класс App внутри данного AppDomain.

1
ответ дан 28 November 2019 в 00:10
поделиться

Я добавил это в свой файл 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;
    }

Затем вызвал его из моего метода OnApplicationStarted () следующим образом:

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

Трудно понять, исправило ли это это, потому что это так прерывисто.

0
ответ дан 28 November 2019 в 00:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: