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<>
调用内核获得合适的处理程序。
我正在尝试通过 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<>
调用内核获得合适的处理程序。