gpt4 book ai didi

c# - 使用 ninject 注入(inject)泛型类型的所有实例

转载 作者:太空狗 更新时间:2023-10-29 17:51:00 25 4
gpt4 key购买 nike

我希望能够使用 ninject 将特定泛型类型的所有实例注入(inject)到一个类中。例如,我有一堆格式类似于的自定义提取器:

public interface IExtract<TEntity> 
{
TEntity ExtractFrom(MyBulkExportedEntity exportedEntity);
}

并且我想使用 ninject 多重绑定(bind)将这些提取器的所有实例注入(inject)到负责处理该文件的类中。

public class ProcessDataExtract
{
/*This isn't valid c# but demonstrates the intent of what i would like to do*/
public ProcessDataExtract(IEnumerable<IExtract<>> allExtractors)
{
}

public void Process(MyBulkExportedEntity exportedEntity)
{
/*loop through all of the extractors and pull relevant data from the object*/
}
}

过去,我通过管理类 (IProvideExtractors) 直接访问内核来完成此操作,但我不喜欢这种方法,想知道是否有人知道更好的方法来执行此操作。通过 ninject 多重绑定(bind),我可以获得所有我有兴趣使用 kernel.GetAll(typeof(IExtract<>)) 的实例。

最佳答案

我在寻找相关的东西:我不想使用约定扩展单独指定所有绑定(bind)。

首先:你需要注入(inject)List<IExtract>并继承IExtract<T> : IExtract .这仅仅是因为在 C# 中您无法指定包含不同泛型的集合的类型。正如您在问题中指出的那样,它是无效的语法-除了这个答案之外还有一个很好的理由。

您稍后可以提取 IExtract 的元素从列表中取出并使用反射来获取泛型类型参数并将其投回。或者,如果您知道要查找的提取器:

public IExtract<T> GetExtractor<T>() {
return (IExtract<T>)Extractors.Find(e => e is ExtractImpl<T>);
}

现在你可能有一堆你想要的类 T绑定(bind)到 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;
}
}

关于c# - 使用 ninject 注入(inject)泛型类型的所有实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10939331/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com