0

我的方法完全有可能是不正确的,但我想在尝试解决之前先概述实际要求。我的方法基于此处提供的详细信息

任务:在面向向导的结构中,BaseWizardStepNavigator根据当前步骤获取对象。例如,如果我在 step 上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实现方法,但我对如何真正让它吐回对象有点迷茫。文档晦涩难懂,我什至不完全确定我是否走在正确的道路上。帮助?

4

1 回答 1

0

最后,我设法让一个实现相当简单地工作。没有必要IBindingGeneratorIProvider实施。

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()Web 应用程序。如果您在自己的代码中使用它,请酌情更改.InSingletonScope(),等等。

于 2016-11-30T11:41:41.930 回答