Question

Let's say that i have a LolCats.Data project that contains various repositories that implements interfaces like this one:

public interface ILolCatRepository
{
    ILolCat Get(Guid id);
    void Save(ILolCat lolcat);
    List<ILolCat> GetAll();
}

In the Get(id) method i need to return a new instance of a type implementing the interface ILolCat. But at the same time I dont want to reference the type LolCat by doing a return new LolCat().

Is there any way for me to let ninject create the instance of the type LolCat for me? Or what's the best pattern here? Not sure if I'm over-thinking this. Maybe it doesn't matter that the repository instantiates LolCat since it returns the interface anyway? On the other hand, if i somehow use Ninject for this, it means that the repository is referencing a specific IOC containers solution which might be bad.

Was it helpful?

Solution

You have a couple of options to avoid doing a new LocalCat():

Option #1

public class LolCatRepository : ILolCatRepository
{
 public ILolCat Get(Guid id)
 {
   return NinjectHelper.Resolve<ILolCat>();
 }
}

Ninject is setup as follows:

Bind<ILolCat>().To<LolCat>();

And helper will be something like:

public static class NinjectHelper
{
 public static T Resolve<T>()
 {
  IKernel kernel = new StandardKernel();
  kernel.Load(Assembly.GetExecutingAssembly());
  return kernel.Get<T>();
 }
}

Option #2 is a bit cleaner and uses constructor injection:

public class LolCatRepository : ILolCatRepository
{
 public List<ILocalCat> _localCats;

 // ninject will inject this list due to the chain of dependency.
 // if it fails, then go with option #1.
 public LolCatRepository(List<ILocalCat> localCats)
 {
  this._localCats = localCats;
 }

 public ILolCat Get(Guid id)
 {
   return this._localCats.FirstOrDefault(lc => lc.Id == id);
 }

 // similarly GetAll
}

OTHER TIPS

Sure, you can have ninject inject an Func<ILolCat> factory into the constructor of ILolCatRepository.

Or you could also create an interface for the factory and use Ninject Factory Extension like

IBindingRoot.Bind<ILolCatFactory>().ToFactory();

On a side note, why are you implementing a new repository for every type? Why no just use an interface like:

public interface IRepository 
{
    T Get<T>(Guid id);

    void Save<T>(T entity);

    ....
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top