Ninject GetBindings 接口<T>

Ninject GetBindings with Interface<T>

我正在尝试通过 Ninject 内核进行设置,如下所示:

kernel.Bind<IPersist<SomeDataItem>>().To<SomeDataRepo>();
kernel.Bind<IPersist<AnotherItem>>().To<AnotherRepo>();

因此,当我的服务接收到 SomeDataItem 的实例时 - 我会找到合适的存储库/商店来保存它:

kernel.GetBindings(typeof(IPersist<>))
      .Where(binding => binding.Service.GenericTypeArguments[0] == typeof(SomeDataItem))

但是 - 我无法让它工作。如果我像上面那样设置容器,我会按预期得到 SomeDataRepo

kernel.GetBindings(typeof(IPersist<SomeDataItem>)) // SomeDataRepo

但这没有结果:

kernel.GetBindings(typeof(IPersist<>)) // Empty list

问题:如何查询我的容器以获取具有通用参数 T 的接口实例 - 其中 T 是动态的?

编辑

好的 - 使用这个我至少可以从 GetBindings():

中得到一些结果
kernel.Bind(typeof(IPersist<>)).To<SomeDataRepo>();

虽然在 collection 上使用了 .where(),但我还没有得到正确的答案。

Bind(typeof(IPersist<>)).To(typeof(GenericDataRepo<>));

然后当你这样做时:

kernel.Get<IPersist<SomeDataItem>>();

你会得到GenericDataRepo<SomeDataItem>

所以我找到了一个非常好的解决方案,它深受这个 post 的启发:。

绑定我做如下,使用Ninject.Extensions.Conventions:

        var kernel = new StandardKernel();

        kernel.Bind(
            x =>
            x.FromAssembliesMatching("*")
                .IncludingNonePublicTypes()
                .SelectAllClasses()
                .InheritedFrom(typeof(IPersist<>))
                .BindSingleInterface());

我使用的结果是:

public class ResultsAgent : IResultsAgent
{
    private static readonly MethodInfo GenericProcessMethod = typeof(ResultsAgent).GetMethod("ProcessGeneric");

    private readonly IResolutionRoot resolutionRoot;

    public ResultsAgent(IResolutionRoot resolutionRoot)
    {
        this.resolutionRoot = resolutionRoot;
    }

    public void Store(SearchResult message)
    {
        GenericProcessMethod.MakeGenericMethod(message.GetType())
            .Invoke(this, new object[] { message });
    }

    public void ProcessGeneric<TMessage>(TMessage message)
        where TMessage : SearchResult
    {
        var handler = this.resolutionRoot.Get<IPersist<TMessage>>();
        Console.WriteLine("ResultsAgent will use: " + handler.GetType().FullName + " to persist");
        handler.Persist(message);
    }
}

ResultAgent 中的智能来自提到的 Whosebug - 它使用反射创建对通用方法 (ProcessGeneric) 的调用,然后使用 Kernel.Get<> 调用内核获得合适的处理程序。