我有一个ASP.NET MVC 5项目,我需要使用基于Web服务的自定义电子邮件服务(长篇故事!但不能改变它。)
我将电子邮件Web服务包装到一个单独的程序集中,并将所有依赖项打包在那里。
在我的ASP.NET MVC 5应用程序中,我正在使用Ninject进行依赖注入,并且它在MVC项目中运行得非常好 - 控制器将它们的依赖项“神奇地”注入,并且使用起来很愉快。
但是现在:对于我的电子邮件发送组件,我想编写一个“模拟”或模拟器,以便在开发时在本地使用。所以基本上,我需要能够将IMailService
绑定到MailService
(实际实现),以及MailServiceSimulator
(我的虚拟实现)。 Ninject支持,没问题:
Bind<IMailService>().To<MailService>().Named("Production");
Bind<IMailService>().To<MailServiceSimulator>().Named("Simulator");
但是:问题是这样的:我在MVC应用程序中注册了Ninject的所有依赖项(在NinjectWebCommon
中的App_Startup
类中) - 但是我想要能够在我的“邮件服务”项目中拥有一个工厂类,可以告诉它返回邮件发送组件的真实实现 - 或模拟器。但是,如何才能访问Ninject内核以获得所需的服务?
不知何故,我需要能够做到
return kernel.Get<IMailService>("Production");
如果需要真正的实现,或
return kernel.Get<IMailService>("Simulator");
如果应该使用IMailService
的开发时间模拟器。
由于我的MVC应用程序已经使用“MailService”程序集作为参考,我无法真正使“MailService”使用“MVC”项目作为参考....所以如何访问Ninject内核(获取从引用的“MailService”程序集中创建的“MVC”程序集在启动时创建?似乎我要进入圈子,一个组件需要另一个,然后另一个需要第一个再次作为依赖.......
有什么想法吗?
答案 0 :(得分:2)
在MailService项目中访问内核或进行DI业务似乎是一个漏洞的抽象。
假设“生产/模拟器”开关位于appSettings中作为“MailSwitch”设置,您可以省略命名绑定并转到:
Bind<IMailService>().To<MailService>()
.When(r => ConfigurationManager.AppSettings.Get("MailSwitch")=="Production");
Bind<IMailService>().To<MailServiceSimulator>()
.When(r => ConfigurationManager.AppSettings.Get("MailSwitch")=="Simulator");