Хотя стандарт C ++ не имеет такого требования, некоторым компиляторам требуется, чтобы все шаблоны функций и классов были доступны в каждой используемой системе переводов. Фактически для этих компиляторов тела шаблонных функций должны быть доступны в файле заголовка. Повторить: это означает, что эти компиляторы не позволят их определять в файлах без заголовка, таких как .cpp-файлы
Существует ключевое слово export , которое должно смягчать этот проблема, но он нигде не близок к тому, чтобы быть портативным.
Самый простой способ - добавить ограничение на ваш общий интерфейс:
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
, который разрешает открытые общие типы.