我正在寻找相关的东西:我不想使用约定扩展单独指定所有绑定。
首先:您需要注入List<IExtract>
和继承IExtract<T> : IExtract
. 这仅仅是因为在 C# 中您不能指定包含不同泛型的集合的类型。正如您在问题中指出的那样,它是无效的语法 - 除了这个答案之外,还有一个很好的理由。
您可以稍后将 的元素IExtract
从列表中拉出并使用反射来获取泛型类型参数并将其转换回来。或者,如果您知道您正在寻找什么提取器:
public IExtract<T> GetExtractor<T>() {
return (IExtract<T>)Extractors.Find(e => e is ExtractImpl<T>);
}
现在你可能有一堆你想要一些T
绑定到 IExtract` 的类。
Bind<IExtract>().To<ExtractImpl<MyEntity>>();
Bind<IExtract>().To<ExtractImpl<YourEntity>>();
在哪里
MyEntity : BaseEntity
YourEntity : BaseEntity
您可以指定一个约定如下
Kernel.Bind(x => x.FromThisAssembly().SelectAllClasses()
.InheritedFrom<BaseEntity>()
.BindWith(new GenericArgumentBindingGenerator(typeof(IExtract<>))));
哪里GenericArgumentBindingGenerator
定义为:
public class GenericArgumentBindingGenerator : IBindingGenerator
{
private readonly Type m_Generic;
public GenericArgumentBindingGenerator(Type generic)
{
if (!generic.IsGenericTypeDefinition)
{
throw new ArgumentException("given type must be a generic type definition.", "generic");
}
m_Generic = generic;
}
public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot)
{
if (type == null)
throw new ArgumentNullException("type");
if (bindingRoot == null)
throw new ArgumentNullException("bindingRoot");
if (type.IsAbstract || type.IsInterface)
{
return Enumerable.Empty<IBindingWhenInNamedWithOrOnSyntax<object>>();
}
var bindings = new List<IBindingWhenInNamedWithOrOnSyntax<object>>();
IBindingWhenInNamedWithOrOnSyntax<object> binding = bindingRoot
.Bind(typeof(IExtract)) // you maybe want to pass typeof(IExtract) to constructor
.To(m_Generic.MakeGenericType(type));
bindings.Add(binding);
return bindings;
}
}