如何使用Scan与"贪婪"构造函数一起使用StructureMap和通用非闭合类型

ahs*_*ele 37 c# structuremap generics asp.net-mvc dependency-injection

在各种Stack Overflow问题和博客文章之间,有关于开放式泛型和StructureMap主题的相当多的文档.不幸的是,我必须遗漏一些东西,因为我尝试使用scan执行配置以及具有"贪婪"构造函数的类实现仍然有效.

我希望StructureMap通过对其实现的接口的引用来获取下面的类的实例.ToCsvService存在于名为Infrastructure的未引用程序集中.IToCsvService存在于名为Core的引用程序集中.你可以看到 ToCsvService有一个"贪婪"的构造函数.

public class ToCsvService<TSource> : IToCsvService<TSource>
{
    public ToCsvService(ICollection<TSource> collection)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

我让StructureMap ToCsvService通过这个ConnectImplementationsToTypesClosing方法了解.

ObjectFactory.Initialize(cfg =>
{
    cfg.Scan(scan =>
    {
        scan.Assembly("Infrastructure");
        scan.WithDefaultConventions();

        // even with this call StructureMap cannot use ToCsvService
        // instance of IToCsvService (though wouldn't expect it to)
        scan.ConnectImplementationsToTypesClosing
            (typeof(IToCsvService<>));
    });
});
Run Code Online (Sandbox Code Playgroud)

ObjectFactory.WhatDoIHave()方法看,StructureMap知道ToCsvService.

PluginType                            Name                                                                                                            Description                                                                                                                          
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
IToCsvService`1 (IToCsvService`1)                                                                                                                                                                                                                                      
Scoped as:  Transient                                                                                                                                                                                                                                                                                  
                                      6202a7ee-89a4-4edd-831d-4867b7dd1a7e                                                                            Configured Instance of Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 
                                      Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null   Configured Instance of Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null                   

但是,当我IToCsvService<CustomerViewModel>在Controller构造函数中指定时,它会抛出异常

StructureMap异常代码:202没有为PluginFamily Core.Services.IToCsvService`1 [[UI.Models.MachineForm,UI,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]],Core,Version = 1.0定义默认实例. 0.0,Culture = neutral,PublicKeyToken = null

我想这是因为StructureMap不知道该怎么处理"贪婪"的ToCsvService构造函数.在某种程度上,我可以使StructureMap能够与这个构造函数一起玩得很好吗?我是否需要从构造函数切换并在实例化后设置集合属性?

问题Structuremap和泛型类型的细节在某种程度上我试图做,但没有利用扫描这样做.Joshua Flanagan提供的答案利用了配置,如果我没有扫描程序集可能会有效,因为我没有参考.For(x).Use(y)ToCsvService

编辑

我想看看是否使用不同的机制让StructureMap识别实例ToCsvService<>会产生影响.它会更改报告的内容ObjectFactory.WhatDoIHave()并抛出不同的异常.这是一个使用的例子AddAllTypesOf.

ObjectFactory.Initialize(cfg =>
{
    cfg.Scan(scan =>
    {
        scan.Assembly("Infrastructure");
        scan.WithDefaultConventions();

        scan.AddAllTypesOf(typeof(IToCsvService<>));
    });
});
Run Code Online (Sandbox Code Playgroud)

使用上面的转储后ObjectFactory.WhatDoIHave()

PluginType                           Name                                                                                                                                 Description                                                                                                                                            
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
IToCsvService`1 (IToCsvService`1)    Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null                        Configured Instance of Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null                   
Scoped as:  Transient

                                     Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null                        Configured Instance of Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null                   
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
IToCsvService`1 (IToCsvService`1)    Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null                        Configured Instance of Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null                   
Scoped as:  Transient

                                     Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null                        Configured Instance of Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

使用此配置,我抛出此异常:

StructureMap异常代码:202没有为PluginFamily System.Collections.Generic.ICollection`1 [[UI.Models.MachineForm,UI,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]]定义的默认实例,mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089

对我来说,异常表明StructureMap知道它需要ICollection<MachineForm>实例化ToCsvService但不知道从哪里获取它.以下是Jimmy关于使用StructureMap和Constructor setter注入评论.但是,如果不添加对基础结构程序集的显式引用,这似乎是不可能的.

有关StructureMap和Generics的Stack Overflow问题

有关StructureMap和Generics的博客文章

Jim*_*ard 10

是否有任何具体的IToCsvService实现?或者只是开放式ToCsvService?

ConnectImplementationsToTypesClosing用于将具体的CustomerViewModelToCsvService之类的东西连接到IToCsvService <>.如果要将开放类连接到打开的接口,则需要:

For(typeof(IToCsvService<>)).Use(typeof(ToCsvService<>));
Run Code Online (Sandbox Code Playgroud)

在这里,我将开放接口类型连接到open类型.