2

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

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

从理论上讲,我希望能够遵循 StructureMap 的开放通用功能,例如:

For(typeof(IRepository<>)).Use(typeof(Repository<>)).

我意识到我不能这样做:

For(typeof(IParser<Range<>>).Use(typeof(RangeParser<>));

我试图通过反射来做到这一点MakeGenericType,但是,我似乎遇到了这种方法的问题。

var requestedType = typeof(IParser<>).MakeGenericType(typeof(Range<>));
For(requestedType).Use(typeof(RangeParser<>));

任何想法将不胜感激。

4

1 回答 1

2

StructureMap 在支持开放泛型方面非常有限。另一方面,使用Simple Injector ,您可以执行以下操作:

// using SimpleInjector.Extensions;

container.RegisterOpenGeneric(typeof(IParser<>), typeof(RangeParser<>));

这将映射IParser<Range<T>>RangeParser<T>where Tis a struct。如果您有多个通用实现,IParser<T>您可以简单地添加额外的实现:

container.RegisterOpenGeneric(typeof(IParser<>), typeof(RangeParser<>));
container.RegisterOpenGeneric(typeof(IParser<>), typeof(ReferenceTypeParser<>));

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

如果有一些重叠,您可以为该RegisterOpenGeneric方法提供一个谓词,如下所示:

container.RegisterOpenGeneric(typeof(IParser<>), typeof(RestrictiveParser<>));
container.RegisterOpenGeneric(typeof(IParser<>), typeof(FallbackParser<>), 
    c => !c.Handled);

这些注册按注册顺序进行评估。

您可以使用泛型类型约束作为自然过滤器,Simple Injector 将遵循它们。如果泛型类型约束不能削减它,你总是可以注册部分开放的泛型类型:

container.RegisterOpenGeneric(typeof(IParser<>), 
    typeof(SomeParser<>).MakeGenericType(typeof(List<>));

在 .NET 的所有 IoC 框架中,Simple Injector 对泛型类型提供了最好的支持:

  • 它理解泛型类型约束。
  • 它允许复杂的嵌套泛型类型映射。
  • 它允许提供部分开放的泛型类型。
  • 它允许将泛型装饰器应用于类型。
  • 它允许基于泛型类型约束有条件地应用泛型装饰器。
  • 它允许使用混合非泛型实现和提供的开放泛型类型的自动确定的封闭版本来注册集合。
于 2013-09-25T18:33:29.103 回答