NInject контекстная привязка, когда метод вызывается слишком много раз

interface IWarrior
{
}

class Samurai : IWarrior
{
}

public class Program
{
    public static void Main(string[] args)
    {
        var kernel = new StandardKernel();

        kernel.Bind<IWarrior>().To<Samurai>().When(i =>
        {
            Console.WriteLine("test");
            return true;
        });

        IWarrior warrior = kernel.Get<IWarrior>();
    }
}

Вот очень простой сценарий, я создаю фиктивный интерфейс + реализацию и связываю их, используя NInject's Contextual Binding и When метод, который return trueи также выводит "тестовое" сообщение на консоль при вызове. я думал When() будет вызван только один раз за Get<>() ожидал, что он выдаст "test" только один раз, но волшебным образом (или нет?^_^) он выдаст 3 раза "test",

test
test
test

Который означает, что When() вызывается 3 раза за один Get<>() запрос (я добавил еще одну реализацию IWarrior и связал ее, затем количество выводов составило 6(3 на привязку)).

Почему это происходит? Мы собираемся поставить несколько нетривиальных (и тоже трудоемких) проверок для каждой привязки, но проблема будет вызывать ее три раза вместо одной.

1 ответ

Решение

Для одиночной активации Ninject оценит, сможет ли он удовлетворить ваш запрос, используя делегата, предоставленного в When, И из-за внутренней реализации Ninject, он может вызывать это несколько раз. Источником этого является исходный код Ninject, доступный на github.

У него нет возможности узнать тип условия или если логика отнимает много времени.

И как примечание: это одна из причин, почему контейнер Ninject намного медленнее для каждого запроса на активацию, чем другие. Именно потому, что он поддерживает расширенные контекстные / условные привязки, где каждый запрос на активацию должен оцениваться с учетом его контекста (а не кэшироваться).

Другие вопросы по тегам