StructureMap - Scan - Общий интерфейс с базовой реализацией и специфическими - PullRequest
2 голосов
/ 12 апреля 2010

У меня есть интерфейс, похожий на этот:

interface IGenericSetupViewModel<T>

Затем у меня есть реализация по умолчанию этого, что-то вроде этого

class GenericSetupViewModel<T> : IGenericSetupViewModel<T>

Для некоторых конкретных классов у меня есть конкретная реализациянапример:

class ContractSetupViewModel : GenericSetupViewModel<Contract>

Теперь я хочу, чтобы StructureMap возвращал правильный экземпляр, когда запрашиваю

ObjectFactory.GetInstance<GenericSetupViewModel<Contract>();

Я хотел бы получить ContractSetupViewModel, когда запрашивал что-то еще,Я хотел бы получить экземпляр

GenericSetupViewModel<T>

Я пытался сделать это:

        StructureMap.ObjectFactory.Configure(x =>
        {
            x.Scan(y =>
            {
                y.TheCallingAssembly();
                y.AddAllTypesOf(typeof(IGenericSetupViewModel<>));
                y.ConnectImplementationsToTypesClosing(typeof(IGenericSetupViewModel<>));
            });
        });

Однако это приводит к тому, что я всегда получаю GenericSetupViewModel, а не ContractSetupViewModel.Я не хочу указывать все конкретные видовые модели, так что, в любом случае, я могу заставить это сканирование работать?

Ответы [ 3 ]

3 голосов
/ 12 апреля 2010

В StructureMap была недолгая ошибка, из-за которой у ConnectImplementationToTypesClosing возникла проблема, если конкретный тип закрытия не реализовал интерфейс напрямую. Как только вы получите последнюю версию StructureMap, будет работать следующий код:

StructureMap.ObjectFactory.Configure(x =>
{
    x.Scan(y =>
    {
        y.TheCallingAssembly();
        y.ConnectImplementationsToTypesClosing(typeof(IGenericSetupViewModel<>));
    });
    x.For(typeof (IGenericSetupViewModel<>)).Use(typeof(GenericSetupViewModel<>));
});
0 голосов
/ 13 апреля 2010

Я не слишком знаком с StructureMap, но может быть, вас обманули по приоритету регистрации?

Поскольку вы сначала вызываете y.AddAllTypesOf(typeof(IGenericSetupViewModel<>));, сначала будет зарегистрирован универсальный класс opene GenericSetupViewModel<T>. Эта регистрация выполнит ваш запрос на разрешение GenericSetupViewModel<Contract>, а более конкретная ContractSetupViewModel регистрация будет проигнорирована.

Тем не менее, образец Flattener ясно показывает, что должна работать открытая регистрация универсального типа и специальные закрытые регистрации универсального типа. Можете ли вы заставить этот шаблон работать с вашими типами?

0 голосов
/ 12 апреля 2010

В вашем GetInstance методе вы должны сделать что-то вроде:

if (AnInstance is GenericSetupViewModel)
    return AnInstance as GenericSetupViewModel;
else if (AnInstance is ContractSetupViewModel)
    return AnInstance as ContractSetupViewModel;
...