c# – 在工厂DI上无法理解ninject(或一般只有IOC容器)?
好吧,所以最近我一直在阅读ninject,但是我很难理解是什么让它更好地解释为什么他们在wiki页面上提到’穷人’的DI.可悲的是我在维基上浏览了所有页面但仍然没有得到它=(.
通常我会将我的服务类包装在处理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>(); } } 非常棒.由于具体类具有隐式绑定,因此一切都会自动处理. 解决方法
IoC容器的好处随着项目的大小而增长.对于小型项目而言,他们的好处与“穷人的DI”相比,就像您的工厂一样.想象一个大型项目,它有数千个类,一些服务在很多类中使用.在这种情况下,您只需要说一次如何解决这些服务.在工厂,你必须为每个班级一次又一次地做.
示例:如果您有一个服务MyService:IMyService和一个需要IMyService的A类,您必须告诉Ninject它将如何解决这些类型,就像您的工厂一样.这里的好处很少.但是一旦你的项目增长并且你添加了一个同样依赖于IMyService的B类,你只需告诉Ninject如何解决B. Ninject已经知道如何获取IMyService.另一方面,在工厂中,您必须再次定义B如何获取其IMyService. 更进一步.在大多数情况下,您不应该逐个定义绑定.而是使用基于约定的配置(Ninject.Extension.Conventions).通过这种方式,您可以将类组合在一起(服务,存储库,控制器,演示者,视图……)并以相同的方式对它们进行配置.例如.告诉Ninject所有以Service结尾的类都应该是单例并发布所有接口.这样,您只需一个配置,添加其他服务时无需进行任何更改. IoC容器也不仅仅是工厂.还有更多.例如.生命周期管理,拦截,…. kernel.Bind( x => x.FromThisAssembly() .SelectAllClasses() .InNamespace("Services") .BindToAllInterfaces() .Configure(b => b.InSingletonScope())); kernel.Bind( x => x.FromThisAssembly() .SelectAllClasses() .InNamespace("Repositories") .BindToAllInterfaces()); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |