#c# #inversion-of-control #castle-windsor
#c# #инверсия контроля #castle-windsor
Вопрос:
Я пытаюсь зарегистрировать тип по соглашению, я упростил свой случай в этом примере:
public abstract class BaseEntity{}
public class EntityA : BaseEntity{}
public class EntityB : BaseEntity{}
public abstract class BaseClass
{
//...
}
public abstract class GenericBaseClass<T> : BaseClass where T : BaseEntity
{
//..
}
public class ConcreteA : GenericBaseClass<EntityA>
{
//...
}
public class ConcreteB : GenericBaseClass<EntityB>
{
//...
}
Я пытаюсь найти способ зарегистрироваться GenericBaseClass
, чтобы вернуться ConcreteA
при запросе GenericBaseClass<EntityA>
. При попытке решить эту проблему я получаю исключение, в котором говорится что-то вроде:
Ошибка активации произошла при попытке получить экземпляр типа GenericBaseClass`1, ключ «»
Если я изменю определение GenericBaseClass<T>
с абстрактного класса на интерфейс, этот регистрационный код будет работать:
container.Register(AllTypes.FromAssemblyContaining<BaseClass>()
.BasedOn(typeof(GenericBaseClass<>))
.WithService.FirstInterface());
Однако мне нужно использовать абстрактный класс, потому что мне нужно написать код внутри него.
Я могу зарегистрировать каждый ConcreteX
класс вручную, но это было бы не очень полезно.
Я пробовал с этим:
container.Register(AllTypes.FromAssemblyContaining<BaseClass>()
.BasedOn(typeof(GenericBaseClass<>))
.WithService.Base());
Отлаживая, я вижу, что тип не добавлен в контейнер.
Я использую Castle Windsor 2.6.
Спасибо.
Комментарии:
1. Нет Windsor 2.6. Вы имели в виду 2.5.4?
Ответ №1:
Это работает:
container.Register(AllTypes.FromAssemblyContaining<ConcreteA>()
.BasedOn(typeof (GenericBaseClass<>))
.WithService.Base());
Если вы видите, что типы не добавляются в контейнер, убедитесь, что вы просматриваете правильную сборку (ту, которая содержит типы реализации, а не типы сервисов).
Комментарии:
1. Не удалось заставить его работать так, как вы предлагали. Это сработало, но мне пришлось добавить тот же код для любого типа ConcreteX: container . Регистр(Компонент. Для(typeof(GenericBaseClass<EntityA>)) .ImplementedBy(typeof(ConcreteA)) .Named(«ConcreteA») );
2. Почему бы и нет? Это именно то, что делает мой код (за исключением части имени)
3. @Hero, твое решение сработало для меня, у меня есть один абстрактный базовый класс и 2 реализации. У меня уже был тот же код, но не хватало . Именованная («…») часть для разграничения регистраций обоих компонентов с использованием одного и того же сервиса. Спасибо!
4. @Hero вы должны ответить на свой вопрос и проголосовать за него, чтобы все знали об этом.