【发布时间】:2012-02-19 18:06:07
【问题描述】:
好的,所以最近我一直在阅读 ninject,但我无法理解是什么使它更好,而不是为什么他们在 wiki 页面上将 do 称为“穷人”的 DI。可悲的是,我浏览了他们在 wiki 上的所有页面,但仍然不明白 =(.
通常我会将我的服务类包装在一个工厂模式中,这样处理 DI:
public static class SomeTypeServiceFactory
{
public static SomeTypeService GetService()
{
SomeTypeRepository someTypeRepository = new SomeTypeRepository();
return = new SomeTypeService(someTypeRepository);
}
}
在我看来很像模块:
public class WarriorModule : NinjectModule {
public override void Load() {
Bind<IWeapon>().To<Sword>();
Bind<Samurai>().ToSelf().InSingletonScope();
}
}
每个类都有它的关联模块,你将它的构造函数绑定到一个具体的实现。虽然 ninject 代码少了 1 行,但我只是没有看到优势,无论何时添加/删除构造函数或更改接口构造函数的实现,都必须像在工厂中那样更改模块不?所以在这里看不到优势。
然后我想我可以像这样想出一个基于通用约定的工厂:
public static TServiceClass GetService<TServiceClass>()
where TServiceClass : class
{
TServiceClass serviceClass = null;
string repositoryName = typeof(TServiceClass).ToString().Replace("Service", "Repository");
Type repositoryType = Type.GetType(repositoryName);
if (repositoryType != null)
{
object repository = Activator.CreateInstance(repositoryType);
serviceClass = (TServiceClass)Activator.CreateInstance(typeof (TServiceClass), new[]{repository});
}
return serviceClass;
}
但是,这很糟糕,原因有两个:1) 它严格依赖于命名约定,2) 它假设存储库永远不会有任何构造函数(不是真的),并且服务的唯一构造函数将是它对应的 repo(也不是真的)。有人告诉我“嘿,这是你应该使用 IoC 容器的地方,在这里会很棒!” 于是我的研究开始了……但我只是没有看到它,并且无法理解它...
ninject 是否可以通过某种方式自动解析类的构造函数而无需特定声明,以便在我的通用工厂中使用它会很棒(我也意识到我可以使用反射手动执行此操作,但这是性能损失和 ninject在他们的页面上说他们不使用反射)。
非常感谢您对此问题的启发和/或展示如何在我的通用工厂中使用它!
编辑:回答
所以感谢下面的解释,我能够完全理解 ninject 的厉害之处,我的通用工厂看起来像这样:
public static class EntityServiceFactory
{
public static TServiceClass GetService<TServiceClass>()
where TServiceClass : class
{
IKernel kernel = new StandardKernel();
return kernel.Get<TServiceClass>();
}
}
非常棒。由于具体类具有隐式绑定,因此一切都会自动处理。
【问题讨论】:
-
通常的破纪录评论:运行到 [.NET 中的依赖注入书籍我的 Mark Seemann](http.commanning.com/seemann)。我无法想象你在拥有这本书的一周内对 DI(模式)和 DI 容器的原因和方式没有信心。
标签: c# inversion-of-control ninject ioc-container