Между различными вопросами и сообщениями в блоге имеется довольно разумная документация по теме открытых дженериков и StructureMap. К сожалению, я должен упустить что-то, поскольку мои попытки использовать scan для выполнения конфигурации вместе с реализацией класса, у которой есть "жадный" конструктор, еще не работают.
Я хочу, чтобы StructureMap захватил экземпляр класса ниже через ссылки на его реализованный интерфейс. ToCsvService существует в unreferenced сборке под названием Infrastructure. IToCsvService существует в ссылочной сборке под названием Core. Как вы видете
ToCsvService имеет "жадный" конструктор.
public class ToCsvService<TSource> : IToCsvService<TSource>
{
public ToCsvService(ICollection<TSource> collection)
{
}
}
Я могу сообщить 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<>));
});
});
Из метода 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> в конструкторе контроллера, он генерирует исключение
Код исключения 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 и общие типы детализирует несколько, я пытаюсь сделать, но не использует сканирование для этого. В ответе , предоставленном Джошуа Фланаганом, используется конфигурация 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<>));
});
});
После использования выше дамп из 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 = нейтральный, PublicKeyToken = b77a5c561934e089
Для меня исключение указывает, что StructureMap знает, что ему требуется ICollection<MachineForm> для создания экземпляра ToCsvService, но не знает, откуда его получить. Которая идет в комментарий Джимми от ниже об использовании StructureMap и Встраивание конструктора set. Однако это не представляется возможным без добавления явной ссылки на сборку инфраструктуры.
Несколько связанных вопросов в StructureMap и Generics
- Структура и общие типы
- Вставка шаблона StructureMap в открытом родовом типе?
- StructureMap Автоматическая регистрация для общих типов с использованием Scan