0

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?

1 Answer 1

2

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();
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.