使用Ninject解析通用存储库

时间:2015-11-18 13:22:47

标签: c# generics ninject ninject.web.mvc

我的UnitOfWork位于GetRepository<T>,我需要使用Ninject解决它。

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

我使用MVC并且我正在 NinjectWebCommon.cs 中加载我的模块:

    /// <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;
        }
    }

知道如何获取GetRepository的实例吗?我尝试创建一个IResolver并将其注入我的UnitOfWork并解析该泛型,但我得到了null。

修改

我想更新解决方案:

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

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

请注意,我使用的是抽象而不是IResolver的具体实现,所以我不认为这是反模式(尽管我可能错了)。我正在试图找出如何使用IResolutionRoot解决这个问题,如下面的答案所示。

修改

在阅读了越来越多的文章后,我认为在使用泛型时这不是一种反模式。避免服务定位器用于泛型的唯一合适的解决方案是反射。所以我特别宁愿使用服务定位器而不是反射。

1 个答案:

答案 0 :(得分:2)

直接回答您的问题是在构造函数中声明IKernel(或更好,IResolutionRoot)依赖关系。但请注意,依赖于DI容器以及在您的类中使用此容器称为服务位置,并且为considered an anti-pattern。您可能需要考虑更改此设计。