Reputation: 13083
I've set up DI with Ninject in my ASP.NET MVC application like this
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 implements IRepository and it contains a constructor that takes contentType parameter which I use for persistance path generation.
Now I have a ServicesController which does not have a default type by itself - it is just a controller that provides JSON data (JSON actions) to consumers from jQuery.
This is how it looks now:
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);
}
}
And this is how other controllers look like (DI is done thru constructor injection here):
public class SectionController : ContentController
{
private IRepository ContentRepository;
public SectionController(IRepository repository)
{
ContentRepository = repository;
}
}
How can I get rid of "new XmlDefaultRepository(contentType)" dependency in ServicesController?
Upvotes: 0
Views: 1229
Reputation: 13083
I've solved this problem by implementing method
_repository.GetSlugsForContentType(contentType, limit, q)
and creating a parameterless default constructor on XmlDefaultRepository implementation of IRepository.
This is the DI way of solving this issue with a Repository factory.
// 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();
Upvotes: 2