我已经在我的ASP.NET MVC应用程序中使用Ninject设置了DI
Bind<IRepository>().To<XmlDefaultRepository>().WhenInjectedInto(typeof(PageController)).WithConstructorArgument("contentType", ContentType.Page);
Bind<IRepository>().To<XmlDefaultRepository>().WhenInjectedInto(typeof(WidgetController)).WithConstructorArgument("contentType", ContentType.Page);
Bind<IRepository>().To<XmlDefaultRepository>().WhenInjectedInto(typeof(SectionController)).WithConstructorArgument("contentType", ContentType.Section);
Bind<IRepository>().To<XmlDefaultRepository>().WhenInjectedInto(typeof(WidgetZoneController)).WithConstructorArgument("contentType", ContentType.WidgetZone);
XmlDefaultRepository实现了IRepository,它包含一个构造函数,该构造函数接受我用于生成持久路径的contentType参数。
现在我有一个ServicesController,它本身没有默认类型 - 它只是一个从jQuery向消费者提供JSON数据(JSON操作)的控制器。
现在的样子:
public class ServicesController : ContentController
{
public ActionResult ContentSlugs(string contentType, string q, int limit)
{
IRepository _repository = new XmlDefaultRepository(contentType); // this instantiation depends on contentType provided by JSON GET request at runtime and I want to somehow replace it with DI
return Json(_repository.GetSlugsForContentType(limit, q), JsonRequestBehavior.AllowGet);
}
}
这就是其他控制器的样子(DI通过构造函数注入完成):
public class SectionController : ContentController
{
private IRepository ContentRepository;
public SectionController(IRepository repository)
{
ContentRepository = repository;
}
}
如何摆脱ServicesController中的“new XmlDefaultRepository(contentType)”依赖关系?
答案 0 :(得分:2)
我通过实现方法
解决了这个问题_repository.GetSlugsForContentType(contentType, limit, q)
并在IRepository的XmlDefaultRepository实现上创建无参数的默认构造函数。
这是使用Repository工厂解决此问题的DI方法。
// ServicesController.cs
// ninject factory example, see IRepositoryFactory interface and its XmlRepositoryFactory implementation
[Inject]
public IRepositoryFactory RepositoryFactory
{
set
{
factory = value;
}
}
private IRepositoryFactory factory;
public ActionResult ContentSlugsThruFactory(string contentType, string q, int limit)
{
IRepository _repository = factory.Create(contentType);
return Json(_repository.GetSlugsForContentType(limit, q), JsonRequestBehavior.AllowGet);
}
// IRepositoryFactory.cs
public interface IRepositoryFactory
{
IRepository Create(string contentType);
}
// XmlRepositoryFactory.cs
public class XmlRepositoryFactory : IRepositoryFactory
{
public IRepository Create(string contentType)
{
return XmlDefaultRepository.Create(contentType);
}
}
// XmlDefaultRepository.cs
public static XmlDefaultRepository Create(ContentType contentType)
{
return new XmlDefaultRepository(contentType);
}
public static XmlDefaultRepository Create(string contentType)
{
return new XmlDefaultRepository(contentType);
}
// global.asax.cs
Bind<IRepositoryFactory>().To<XmlRepositoryFactory>().InSingletonScope();