mare
mare

Reputation: 13083

How to use non-default constructors with Ninject?

How to use Ninject with a sample code for interface and its implementation like this:

public interface IRepository
{
    // common methods for all content types
    void Insert(BaseContentObject o);
    void Update(BaseContentObject o);
    void Delete(string slug);
    void Delete(ContentType contentType, string slug);
    IEnumerable<BaseContentObject> GetInstances();
    BaseContentObject GetInstance(ContentType contentType, string slug);
    BaseContentObject GetInstance(string contentType, string slug);
    BaseContentObject GetInstance(string slug);
    IEnumerable<string> GetSlugsForContentType(int limit = 0, string query = "");
    ContentList GetContentItems();
    bool IsUniqueSlug(string slug);
    string ObjectPersistanceFolder { get; set; }
}

public class XmlDefaultRepository : IRepository
{
    private ContentType SelectedType;

    public XmlDefaultRepository(string contentType)
    {
        SelectedType = (ContentType) Enum.Parse(typeof(ContentType), contentType);
    }

    public void Insert(Models.ContentClasses.BaseContentObject o)
    {
        throw new NotImplementedException();
    }

    // ...
}

public class PageController : BaseController
{
    private IRepository ContentRepository { get; private set; }

    public PageController(IRepository repository)
    {
        ContentRepository = repository;
    }

    // 
    // GET: /{slug}
    // GET: /Pages/{slug}
    public ActionResult Display(string slug)
    {
        // sample repository usage
        Page page = ContentRepository.GetInstance(slug);
        // ...
    }
}

My code does not contain default constructor because I don't need one (even if wanted to create it I couldn't because I always require the content type to be provided.

I cannot make a default constructor because there is logically no default content type to be provided.

This is the exception that Ninject produces when trying to load my ASP.NET MVC page.

*Error activating string

No matching bindings are available, and the type is not self-bindable.

Activation path:

  1. Injection of dependency string into parameter contentType of constructor of type XmlDefaultRepository
  2. Injection of dependency IRepository into parameter repository of constructor of type PageController
  3. Request for IController

Suggestions:

  1. Ensure that you have defined a binding for string.
  2. If the binding was defined in a module, ensure that the module has been loaded into the kernel.
  3. Ensure you have not accidentally created more than one kernel.
  4. If you are using automatic module loading, ensure the search path and filters are correct.*

Upvotes: 0

Views: 1978

Answers (1)

Ruben Bartelink
Ruben Bartelink

Reputation: 61893

You shouldnt need to introduce a default ctor just to please Ninject.

Assuming you're using V2, the semantics for how a constructor is chosen are detailed here

(BTW By default, the string type is not treated as a resolvable type OOTB, but you should be able to Bind ContentType To something and have that constructor invoked).

If none of the above gets you moving, can you please supply a usage scenario and/or an exception detailing the issue you're having.

EDIT: It's not clear to me at this point that you're definitely in a situation where you shouldnt be adding a ConstructorArgument ((probably via WithConstructorArgument() IIRC) to your Bind<T>() statement.

Upvotes: 3

Related Questions