DAG
DAG

Reputation: 2630

Resolve Generic Repository with Ninject

I have my UnitOfWork with GetRepository<T> and I need to get it resolved with Ninject.

    public TRepository GetRepository<TRepository>() where TRepository : class, IRepository
    {
        throw new NotImplementedException();
    }

I use MVC and I'm loading my modules in the NinjectWebCommon.cs like that:

    /// <summary>
    /// Creates the kernel that will manage your application.
    /// </summary>
    /// <returns>The created kernel.</returns>
    private static IKernel CreateKernel()
    {
        INinjectModule[] modules = { new CommonModule(), new ServicesModule(), new BusinessModule(), new DataModule() };

        var kernel = new StandardKernel(modules);

        try
        {
            kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
            kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

            RegisterServices(kernel);
            return kernel;
        }
        catch
        {
            kernel.Dispose();
            throw;
        }
    }

Any idea how to get the instance of GetRepository? I've tried creating an IResolver and injecting it into my UnitOfWork and resolving that generic, but I get null.

EDIT:

I would like to update the solution:

    public UnitOfWork(IDbContext context, IKernel resolver)
    {
        _context = context;
        _resolver = resolver;
    }

    public TRepository GetRepository<TRepository>() where TRepository : class, IRepository
    {
        return (TRepository)_resolver.GetService(typeof(TRepository));
    }

Note that I'm using an abstraction and not a concrete implementation of IResolver, so I don't see this as an anti pattern (I might be wrong though). I'm trying to figure out how to solve this using IResolutionRoot as suggested in answer below.

EDIT:

After reading more and more articles I'm of the idea that this is not an anti pattern when working with generics. The only suitable solution to avoid service locator for generics is reflection. So I particularly rather use the service locator than reflection.

Upvotes: 0

Views: 406

Answers (1)

Yacoub Massad
Yacoub Massad

Reputation: 27861

A direct answer to your question is to declare an IKernel (or better, an IResolutionRoot) dependency in the constructor. However, please note that having a dependency on the DI container and usage of this container inside your class is called service location and is considered an anti-pattern. You might want to consider changing the design of this.

Upvotes: 2

Related Questions