Между различными вопросами и сообщениями в блоге имеется довольно разумная документация по теме открытых дженериков и 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