StructureMap和嵌套泛型 [英] StructureMap and Nested Generics

查看:80
本文介绍了StructureMap和嵌套泛型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am wondering if there is a way to wire up nested generics within StructureMap without having to specify the internal type or create type specific interfaces. I realize that this is a bit confusing, so a coding example might be a better explanation of the functionality that I am looking for.

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

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

Theoretically, I would like to be able to follow StructureMap's open generic capabilities such as this:

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

我意识到我无法做到这一点:

I realize that I cannot do this:

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

我试图通过反射的MakeGenericType来实现,但是,我似乎遇到了这种方法的问题.

I have tried to do it via reflection's MakeGenericType, however, I seem to be running into issues with that approach.

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

任何想法都将不胜感激.

Any ideas would be greatly appreciated.

推荐答案

在支持开放泛型时,StructureMap非常有限.另一方面,使用简单注入器,您可以执行以下操作:

StructureMap is quite limited when it comes to support for open generics. With Simple Injector on the other hand you can do the following:

// using SimpleInjector.Extensions;

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

这会将IParser<Range<T>>映射到RangeParser<T>,其中Tstruct.如果您有IParser<T>的多个通用实现,则可以简单地添加其他实现:

This will map IParser<Range<T>> to RangeParser<T> where T is a struct. If you have multiple generic implementations for IParser<T> you can simply add extra implementations:

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

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

The only thing you need to make sure is that the registrations don't overlap. Simple Injector will throw an exception when you try to resolve (or inject) an closed IParser<T> type that can be handled by multiple registrations.

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

In case there is some overlap, you can supply a predicate to the RegisterOpenGeneric method like this:

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

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

These registrations are evaluated in order of registration.

您可以使用通用类型约束,因为自然过滤器将由Simple Injector跟随.如果通用类型约束没有减少,您可以随时注册部分打开的通用类型:

You can use generic type constraints as natural filters and Simple Injector will follow them. If generic type constraints don't cut it, you can always register partial open generic types:

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

在所有用于.NET的IoC框架中,Simple Injector对通用类型具有最好的支持:

From all IoC frameworks for .NET, Simple Injector has the best support for generic typing:

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

这篇关于StructureMap和嵌套泛型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆