Ninject для возврата имплентации на основе перечислителя

Вполне возможно, что мой подход неверен, но я бы хотел изложить фактические требования, прежде чем пытаться решить. Мой подход основан на деталях, представленных здесь

Задача: в волшебно-ориентированной структуре получить BaseWizardStepNavigator Объект на основе текущего шага. Например, если я на шаге WizardStep.Step1, вернуть экземпляр Step1Navigator, Пример Step1Navigator должен иметь любые инжектированные сборки, поставляемые в его конструкторе, так что если у меня есть;

public class Step1Navigator : BaseWizardStepNavigator
{
    private readonly ISomeReader _reader;
    public Step1Navigator(ISomeReader reader)
        : base(WizardSteps.Step1)
    {
        _reader = reader;
    }
}

... этот аргумент reader заполнен соответствующей реализацией.

Моя идея состоит в том, что у меня был бы объект менеджера, который может создать экземпляр ninject, передавая все реализации базового класса (с соответствующими инъекциями IoC) так, чтобы;

public class NavigatorManager
{
    private readonly List<BaseWizardStepNavigator> _navigators;
    public class NavigatorManager(IEnumerable<BaseWizardStepNavigator> navigators)
    {
         _navigators = new List<BaseWizardStepNavigator>(navigators);
    }
    public BaseWizardStepNavigator Get(WizardStep step)
    {
         return _navigators.FirstOrDefault(n => n.Step == step);
    }
}

В конечном итоге будет 10 шагов мастера с соответствующими навигаторами, чтобы определить следующий шаг, но для этого им потребуется время от времени попадать в БД.

Моя текущая попытка и выполнение привязки в NinjectModule где я использую Ninject и Ninject.Conventions;

Модуль (метод загрузки);

Kernel.Bind(s => s.FromAssemblyContaining(typeof(BaseWizardStepNavigator))
                    .SelectAllClasses()
                    .WhichAreNotGeneric()
                    .InheritedFrom<BaseWizardStepNavigator>()
                    .BindWith<NavigatorBinding>());
var test = Kernel.GetAll<BaseWizardStepNavigator>();

Затем другие классы для привязок и провайдера;

public class NavigatorBinding : IBindingGenerator
{
    public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot)
    {
        if (type.IsInterface || type.IsAbstract)
        {
            yield break;
        }

        yield return bindingRoot.Bind(typeof(BaseWizardStepNavigator)).ToProvider<NavigatorProvider>();
    }
}

public class NavigatorProvider : IProvider<BaseWizardStepNavigator>
{
    public object Create(IContext context)
    {
        return null;
    }

    public Type Type { get { throw new NotImplementedException(); } }
}

Теперь пока звонок kernel.GetAll<BaseWizardStepNavigator>() вызывает Provider методы реализации, я немного растерялся относительно того, как заставить его выплевывать объекты. Документация неясна, и я не совсем уверен, что даже на правильном пути. Помогите?

1 ответ

Решение

Мне удалось заставить реализацию работать довольно просто в конце. Там не было никакой необходимости IBindingGenerator или же IProvider Реализации.

Код для Step1Navigator а также NavigatorManager остается такой же.

NinjectModule код привязки изменяется на;

// set the navigator bindings
Kernel.Bind(s => s.FromAssemblyContaining(typeof(BaseWizardStepNavigator))
                  .SelectAllClasses()
                  .WhichAreNotGeneric()
                  .InheritedFrom<BaseWizardStepNavigator>()
                  .BindAllBaseClasses()
                  .Configure(c => c.InRequestScope())
                  );

// pass in all children of BaseWizardStepNavigator to the manager instance
Bind<NavigatorManager>().ToSelf()
                        .InRequestScope()
                        .WithConstructorArgument(typeof(IEnumerable<BaseWizardStepNavigator>),
                                                    n => n.Kernel.GetAll<BaseWizardStepNavigator>());

.InRequestScope() специфично для веб-приложений. Измените соответствующим образом, если вы используете это в своем собственном коде для .InSingletonScope(), так далее.

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