C# StructureMap和嵌套泛型

C# StructureMap和嵌套泛型,c#,generics,structuremap,simple-injector,C#,Generics,Structuremap,Simple Injector,我想知道是否有一种方法可以连接StructureMap中的嵌套泛型,而不必指定内部类型或创建特定于类型的接口。我意识到这有点让人困惑,所以一个编码示例可能是对我正在寻找的功能的更好解释 public interface IParser<T> { } public class Range<T> where T : struct { } public class RangeParser<T> : IParser<Range<T>> { }

我想知道是否有一种方法可以连接
StructureMap
中的嵌套泛型,而不必指定内部类型或创建特定于类型的接口。我意识到这有点让人困惑,所以一个编码示例可能是对我正在寻找的功能的更好解释

public interface IParser<T> { }
public class Range<T> where T : struct { }
public class RangeParser<T> : IParser<Range<T>> { }

任何想法都将不胜感激。

StructureMap在支持开放泛型方面相当有限。另一方面,您可以执行以下操作:

// using SimpleInjector.Extensions;

container.RegisterOpenGeneric(typeof(IParser<>), typeof(RangeParser<>));
唯一需要确保的是注册不会重叠。当您尝试解析(或注入)可由多个注册处理的已关闭的
IParser
类型时,Simple Injector将引发异常

如果存在一些重叠,您可以向
RegisterOpenGeneric
方法提供如下谓词:

container.RegisterOpenGeneric(typeof(IParser<>), typeof(RestrictiveParser<>));
container.RegisterOpenGeneric(typeof(IParser<>), typeof(FallbackParser<>), 
    c => !c.Handled);
container.RegisterOpenGeneric(typeof(IParser)、typeof(RestrictiveParser));
container.RegisterOpenGeneric(typeof(IParser)、typeof(FallbackParser),
c=>!c.Handled);
这些注册按注册顺序进行评估

您可以将泛型类型约束用作自然过滤器,简单的注入器将遵循它们。如果泛型类型约束未将其剪切,则始终可以注册部分打开的泛型类型:

container.RegisterOpenGeneric(typeof(IParser<>), 
    typeof(SomeParser<>).MakeGenericType(typeof(List<>));
container.RegisterOpenGeneric(typeof(IParser)),
typeof(SomeParser).MakeGenericType(typeof(List));
在所有针对.NET的IoC框架中,Simple Injector对泛型类型的支持最好:

  • 它理解泛型类型约束
  • 它允许复杂的嵌套泛型类型映射
  • 它允许提供部分打开的泛型类型
  • 它允许对类型应用泛型修饰符
  • 它允许根据泛型类型约束有条件地应用泛型装饰器
  • 它允许使用混合了非泛型实现和所提供的开放泛型类型的自动确定关闭版本的集合注册集合

请在标记处指定语言。StructureMap在泛型类型方面的能力相当有限。我认为这不容易做到。我可以推荐一个不同的IoC容器吗?@Steven:我愿意接受任何/所有建议!顺便问一句。您是否尝试过:
For(typeof(IParser)。Use(typeof(RangeParser))
?@Steven:我相信这在我发布的有限场景中可能会起作用。尽管如此,我有多个实现IParser接口的具体解析器,因此,我不确定它如何区分各种具体类。例如:DifferenticConcreteParser:IParser
// using SimpleInjector.Extensions;

container.RegisterOpenGeneric(typeof(IParser<>), typeof(RangeParser<>));
container.RegisterOpenGeneric(typeof(IParser<>), typeof(RangeParser<>));
container.RegisterOpenGeneric(typeof(IParser<>), typeof(ReferenceTypeParser<>));
container.RegisterOpenGeneric(typeof(IParser<>), typeof(RestrictiveParser<>));
container.RegisterOpenGeneric(typeof(IParser<>), typeof(FallbackParser<>), 
    c => !c.Handled);
container.RegisterOpenGeneric(typeof(IParser<>), 
    typeof(SomeParser<>).MakeGenericType(typeof(List<>));