如果您的 IFeature 实现没有其他依赖项,那么使用您的方法就很好而且非常简单。
例如,假设您有 2 个 IFeature 实现 - SomeFeature 和 OtherFeature,它们都具有无参数构造函数。
正如你所建议的,你的工厂实现将是这样的:
public class FeatureFactory: IFeatureFactory
{
IFeature CreateFeature(string input)
{
if(input=="SomeFeature")
{
return new SomeFeature();
}
else
{
return new OtherFeature ();
}
}
}
然而,当您的 IFeature 实现使用这种方法有自己的依赖项时,您就失去了使用 Ninject 和 IoC 的意义。
例如,假设某个功能看起来像这样:
public class SomeFeature : IFeature
{
private readonly IDependency1 _dependency1;
private readonly IDependency2 _dependency2;
public SomeFeature (IDependency1 dependency1, IDependency2 dependency2)
{
_dependency1=dependency1;
_dependency2=dependency2;
}
string execFeature()
{
//Some code here...
}
}
其他功能类似...
public class OtherFeature: IFeature
{
private readonly IDependency1 _dependency1;
private readonly IDependency2 _dependency2;
public OtherFeature(IDependency1 dependency1, IDependency2 dependency2)
{
_dependency1=dependency1;
_dependency2=dependency2;
}
string execFeature()
{
//Some code here...
}
}
现在你的工厂会变成这样:
public class FeatureFactory: IFeatureFactory
{
IFeature CreateFeature(string input)
{
if(input=="SomeFeature")
{
return new SomeFeature(new Dependency1Implementation(), new Dependency2Implementation());
}
else
{
return new OtherFeature(new Dependency1Implementation(), new Dependency2Implementation());
}
}
}
这是您可以使用 ninject.extensions.factory 功能的地方
通过使用容器来为您解决此依赖关系。(此依赖关系可以有自己的依赖关系,并且很快就会变得混乱)。
正如其他人提到的,您可以使用命名绑定来绑定每个 IFeature 实现。
Bind<IFeature>().To<SomeFeature>().Named("SomeFeature");
Bind<IFeature>().To<OtherFeature>().Named("OtherFeature");
当然你也应该绑定其他依赖项
Bind<IDependency1>().To<Dependency1Implementation>();
Bind<IDependency2>().To<Dependency2Implementation>();
然后使用工厂扩展将 IFeatureFactory 绑定到 Factory。
Bind<IFeatureFactory>().ToFactory();
您要做的就是为 IFeatureFactory 中的每个 IFeature 实现创建工厂方法,并根据名为绑定的功能调用它 Get...。
public interface IFeatureFactory
{
IFeature GetSomeFeature();
IFeature GetOtherFeature();
}
现在 ninject 将为您实现(!)这个类,并知道为每个方法选择哪个实现。(不需要服务定位器......)
您可以在客户端的输入上使用 switch 语句来选择要调用的工厂方法,或者您可以将其包装在某个包含 switch 语句的提供程序类中,在这两种情况下,您都不必为IFeature 自己实现。
当然,如果需要以及其他更复杂的事情,您可以通过工厂方法将参数传递给实现构造函数。
我建议你阅读this了解更多信息。
Edit
我想强调的是,您不必为每个实现编写工厂方法,您可以对所有实现使用相同的方法(这是可能的,但更复杂)。
为此,您需要创建自定义实例提供程序来检测要实例化的实现(例如根据工厂参数),有关此内容的更多信息,请参见上面的链接和here.