编程语言
首页 > 编程语言> > C#-获取通用服务类型的所有实现-包括开放通用

C#-获取通用服务类型的所有实现-包括开放通用

作者:互联网

背景

我正在编写一些集成测试,在其中测试特定接口IQueryMapping< TSource,TDest>的实现.存在该接口以从IQueryable< TSource>映射.到IQueryable< TDest>.我要确保他们这样做
使用Entity Framework编译查询时不会抛出异常.

任务

我很懒,我不想每次创建新映射都必须更新测试!我要做的就是确保应用程序使用的每个映射都可以通过测试.我可以引导我的容器,然后找到向其注册的所有实现,如下所示:

from r in Container.GetCurrentRegistrations()
let t = r.ServiceType
where t.IsGenericType && t.GetGenericTypeDefinition() == typeof (IQueryMapping<,>)
select r.GetInstance()

到现在为止还挺好!

问题

除了具体的实现,我还有一个默认的开放式通用映射器,该映射器执行基本的自动属性映射(请记住,我很懒,不想手动执行此操作!)

container.RegisterOpenGeneric(typeof(IQueryMapping<,>), typeof(DefaultAutoMapping<,>));

不幸的是,在Container.GetCurrentRegistrations()调用中似乎没有出现开放的泛型.从docs

Returns an array with the current registrations. This list contains all explicitly registered types, and all implicitly registered instances. Implicit registrations are all concrete unregistered types that have been requested, all types that have been resolved using unregistered type resolution (using the ResolveUnregisteredType event), and requested unregistered collections. Note that the result of this method may change over time, because of these implicit registrations.

我真正想要的是让Simple Injector告诉我有关每次请求的IQueryMapping<,>的信息.在所有已注册的组件中.

例如,如果我离开了IQueryMapping< Foo,Bar>作为开放的通用DefaultAutoMapping<,>并且已注册的组件具有构造函数签名

public MyComponent(IQueryMapping<Foo, Bar> mapping)
{
   ...
}

我希望容器告诉我有关这种专门的IQueryMapping<,>的信息,以便我可以请求它的一个实例并通过测试运行它.

解决方法:

调用RegisterOpenGeneric将在后台将委托挂接到ResolveUnregisteredType事件上.从根本上讲,这意味着容器本身完全不知道注册,并且仅当请求注册抽象的封闭版本时才添加注册.要么直接使用对GetInstance()的调用,要么间接地解决,因为可以解析依赖于该抽象的类型.

这里的技巧是在调用GetCurrentRegistrations()之前先调用Verify().调用Verify()将导致容器构建所有表达式树,编译所有委托,并创建容器已知的所有注册的所有实例.这将迫使容器添加该开放泛型抽象的每个找到的封闭泛型版本的注册.

长话短说:首先调用Verify().

标签:generics,c,simple-injector
来源: https://codeday.me/bug/20191120/2042314.html