Autofac и RegisterGeneric - ограниченные допустимые дженерики

Хотя стандарт C ++ не имеет такого требования, некоторым компиляторам требуется, чтобы все шаблоны функций и классов были доступны в каждой используемой системе переводов. Фактически для этих компиляторов тела шаблонных функций должны быть доступны в файле заголовка. Повторить: это означает, что эти компиляторы не позволят их определять в файлах без заголовка, таких как .cpp-файлы

Существует ключевое слово export , которое должно смягчать этот проблема, но он нигде не близок к тому, чтобы быть портативным.

0
задан Andrzej 13 July 2018 в 17:37
поделиться

1 ответ

Самый простой способ - добавить ограничение на ваш общий интерфейс:

public interface IInjectator<T> 
    where T : InjectableClass 
{ }

Таким образом .net не позволит вам получить недопустимый тип.

Если вы не можете этого сделать, нет простого способа изменить поведение RegisterGeneric, как я могу видеть, это подписаться на событие OnActivated и выбросить исключение:

builder.RegisterGeneric(typeof(Foo<>))
        .As(typeof(IFoo<>))
        .OnActivated(e =>
        {
            Boolean isValid = e.Component.Services
                .OfType<IServiceWithType>()
                .Where(s => s.ServiceType.IsConstructedGenericType
                            && s.ServiceType.GetGenericTypeDefinition() == typeof(IFoo<>)
                            && s.ServiceType.GetGenericArguments()[0].IsAssignableTo<IBar>())
                .Any();

            if (!isValid)
            {
                throw new Exception("boom");
            }
        });

Если вы не хотите генерировать исключение, вы можете реализовать свой собственный IRegistrationSource. Вы можете посмотреть исходный код нативного OpenGenericRegistrationSource , который разрешает открытые общие типы.

1
ответ дан Cyril Durand 17 August 2018 в 12:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: