Привязки на основе параметров в ninject 2.0

Я хочу использовать условное связывание в ninject, основываясь на переданных параметрах. У меня есть что-то вроде ниже:

public class Subject
{
}

public interface ITarget
{
}

public class Target1 : ITarget
{
}

public class Target2 : ITarget
{
}

И теперь мне нужно создать экземпляр интерфейса ITarget:

    public void MethodName(IKernel kernel)
    {
        ITarget target1 = kernel.Get<ITarget>(new Parameter("name", new Subject(), true)); // Should be instance of Target1
        ITarget target2 = kernel.Get<ITarget>(); // Should be instance of Target2
    }

У меня проблемы с определением правильных привязок. Я попробовал следующее:

kernel.Bind<ITarget>().To<Target1>().When(Predicate);
kernel.Bind<ITarget>().To<Target2>();

private bool Predicate(IRequest request)
{
    IParameter parameter = request.Parameters.Count == 0 ? null : request.Parameters[0];
    if (parameter == null)
    {
        return false;
    }
    object parameterValue = parameter.GetValue( /*what to put here?*/);
    return parameterValue != null && parameterValue.GetType().IsAssignableFrom(typeof(Subject));
}

но я не знаю, как получить значение переданного параметра. Мне нужно передать экземпляр IContext в метод GetValue, но я не знаю, как получить действительный экземпляр IContext. Или, может быть, есть лучший способ выполнить мою задачу?

РЕДАКТИРОВАТЬ: BindingMetadata это лучший способ решить мою проблему. Посмотрите Контекстные привязки с Ninject 2.0 для деталей

С уважением

2 ответа

Решение

Есть ли IRequest.ParentContext не дать вам достаточно?

Кроме того, если все, что вам нужно, это использовать имя для устранения неоднозначности нескольких экземпляров [и вы будете в состоянии предоставлять его каждый раз и будете рады работать в таком явном порядке расположения службы вместо использования DI, как и предполагалось в IDeity] то есть перегрузка Get с именем и WithName для на стороне Bind.

РЕДАКТИРОВАТЬ: провел некоторое время в Reflector, но я все еще не намного мудрее. Механизм параметров, по-видимому, предназначен для переопределения определенных значений в контексте фактического связывания, а не как часть выбора применяемого связывания. Установление контекста выполняется только в одном месте (хотя Context имеет публичный ctor) так что не похоже, что для этого есть аккуратная фабрика.

Действительно ли ваш сценарий соответствует механизму ограничений (из которых использование имени для фильтрации является просто самым простым случаем). вы можете выразить Get как то так:

_kernel.Get<ITarget>( (Ninject.Planning.Bindings.BindingMetadata metadata)=>metadata.Has("x") );

Надеюсь, Ian Davis скоро Ian Davis как я бы тоже хотел узнать ответ:D

IIRC запрос может быть частью нескольких контекстов. Параметры, которые вы видите, являются только параметрами, указанными в вызове Get. В приведенном вами примере вы должны иметь возможность передать значение null как IContext, чтобы получить экземпляр вашего объекта. Поскольку вы предоставляете объект вместо обратного вызова, параметр создает обратный вызов как ctx => value ->, таким образом, обратный вызов не использует предоставленное вами значение контекста.

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