使用 Ninject 解析通用存储库

Resolve Generic Repository with Ninject

我有我的 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 解决此问题,如以下答案中所建议。

编辑:

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

您问题的直接答案是在构造函数中声明一个 IKernel(或者更好的是 IResolutionRoot)依赖项。但是,请注意,依赖于 DI 容器并在 class 中使用此容器称为服务位置,即 considered an anti-pattern。您可能要考虑更改此设计。