Ninject 到 return 基于枚举器的实现
Ninject to return implementation based on enumerator
我的方法完全有可能不正确,但我想在尝试解决之前先概述实际要求。我的方法基于提供的详细信息 here
任务:在向导式结构中,根据当前步骤得到一个BaseWizardStepNavigator
对象。例如,如果我在步骤 WizardStep.Step1
,return 实例 Step1Navigator
。 Step1Navigator
的实例应该在其构造函数中提供任何注入程序集,这样如果我有;
public class Step1Navigator : BaseWizardStepNavigator
{
private readonly ISomeReader _reader;
public Step1Navigator(ISomeReader reader)
: base(WizardSteps.Step1)
{
_reader = reader;
}
}
...参数 reader
填充了适当的实现。
我的想法是,我有一个管理器对象,ninject 可以通过传入基础 class 的所有实现(通过适当的 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>();
然后是绑定和提供程序的其他 class;
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
实现方法,但我对如何实际让它吐回对象有点迷茫。文档晦涩难懂,我什至不确定我是否走在正确的道路上。帮忙?
我最终设法让一个实现相当简单地工作。不需要 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()
特定于 Web 应用程序。如果您在自己的代码中使用它,请适当更改为 .InSingletonScope()
,等等
我的方法完全有可能不正确,但我想在尝试解决之前先概述实际要求。我的方法基于提供的详细信息 here
任务:在向导式结构中,根据当前步骤得到一个BaseWizardStepNavigator
对象。例如,如果我在步骤 WizardStep.Step1
,return 实例 Step1Navigator
。 Step1Navigator
的实例应该在其构造函数中提供任何注入程序集,这样如果我有;
public class Step1Navigator : BaseWizardStepNavigator
{
private readonly ISomeReader _reader;
public Step1Navigator(ISomeReader reader)
: base(WizardSteps.Step1)
{
_reader = reader;
}
}
...参数 reader
填充了适当的实现。
我的想法是,我有一个管理器对象,ninject 可以通过传入基础 class 的所有实现(通过适当的 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>();
然后是绑定和提供程序的其他 class;
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
实现方法,但我对如何实际让它吐回对象有点迷茫。文档晦涩难懂,我什至不确定我是否走在正确的道路上。帮忙?
我最终设法让一个实现相当简单地工作。不需要 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()
特定于 Web 应用程序。如果您在自己的代码中使用它,请适当更改为 .InSingletonScope()
,等等