我正在尝试使用Ninject,并修改我用Structure Map编写的代码,以查看它有多容易。在这个基础代码中,我有一个对象图,通过Structure Map注册表具有不同的配置,并且在运行时通过数据库中的值选择要使用的对象(在这种情况下,返回一些注入对象的WCF服务体)。例如(使用Structure Map代码):
Registry 1为IBusinessContext、IRules和ILogger类型设置所有默认值。这只是将GenericContext/Logger/Rules类型与接口一起添加,没有其他特殊化。
在 Structure Map 中,这一切都能正常进行(取决于使用的新或旧语法)。然而,当我使用 Ninject 时,我遇到了一个问题:期望未命名实例成为默认实例(这并不是 Ninject 的工作方式,我明白这一点)。这导致我进行了一些研究,所有的研究都表明使用具名实例是非常糟糕的想法。我知道可以使用自动注册或属性来设置名称或请求某个类型以实现更好的方法,但在我描述的系统中,需要在运行时找出在树的顶部要请求什么配置(并让 IoC 框架基于已注册的类型或规则来处理其余部分)。
那么...我是否只是在错误地使用 IoC 概念,期望通过名称请求我的顶层对象?还是通常有更好的方式来实现我所尝试的事情?我应该使用像 MEF 这样的东西,将这一切都视为插件吗?
请注意,我不像一个愚蠢的工厂,每一级代码都会从容器中请求类型 x 的实例,而仅限于启动操作。感谢您的时间和帮助 :)
Registry 1为IBusinessContext、IRules和ILogger类型设置所有默认值。这只是将GenericContext/Logger/Rules类型与接口一起添加,没有其他特殊化。
public GenericRegistry()
{
// Set up some generic bindings here
For<ILogger>().Use<Loggers.GenericLogger>();
For<IBusinessRule>().Use<Rules.StandardRule>();
For<IBusinessContext>().Use<Contexts.GenericBusinessContext>();
For<ILoggerContext>().Use<Loggers.GenericLoggerContext>();
}
Registry 2将IBusinessContext设置为使用SpecialisedContext类,并告诉ctor使用SpecializedLogger。IBusinessContext的实例名为“SpecializedContext”。
public SpecializedRegistry()
{
// Old style syntax as it affects the default for IBusinessContext
// Perhaps a hint at what I'm doing?
InstanceOf<IBusinessContext>().Is.OfConcreteType<Contexts.SpecializedBusinessContext>().Named(SpecializedInstanceName).Ctor<ILogger>().Is<Loggers.SpecialisedLogger>();
}
在 Structure Map 中,这一切都能正常进行(取决于使用的新或旧语法)。然而,当我使用 Ninject 时,我遇到了一个问题:期望未命名实例成为默认实例(这并不是 Ninject 的工作方式,我明白这一点)。这导致我进行了一些研究,所有的研究都表明使用具名实例是非常糟糕的想法。我知道可以使用自动注册或属性来设置名称或请求某个类型以实现更好的方法,但在我描述的系统中,需要在运行时找出在树的顶部要请求什么配置(并让 IoC 框架基于已注册的类型或规则来处理其余部分)。
那么...我是否只是在错误地使用 IoC 概念,期望通过名称请求我的顶层对象?还是通常有更好的方式来实现我所尝试的事情?我应该使用像 MEF 这样的东西,将这一切都视为插件吗?
请注意,我不像一个愚蠢的工厂,每一级代码都会从容器中请求类型 x 的实例,而仅限于启动操作。感谢您的时间和帮助 :)