2015-06-02 2 views
2

У меня есть интерфейс, как так:Замок Виндзор: Регистрация по соглашению, открытые дженерики

public interface IGenericRepository<T> 

У меня есть базовый класс, как так:

public abstract class GenericRepository<T> : IGenericRepository<T> where T : class 

У меня есть класс, как так:

public class AGenericRepository<T> : GenericRepository<T> where T : class 

Без согласия, я успешно зарегистрирован так:

container.Register(
    Component.For(typeof(GenericRepository<>)).ImplementedBy(typeof(AGenericRepository<>)) 
); 

Я могу успешно решить объект следующим образом:

var robot = container.Resolve<GenericRepository<Android>>(); 

Однако при попытке зарегистрировать по соглашению следующим образом:

container.Register(Classes.FromThisAssembly() 
          .BasedOn(typeof(GenericRepository<>)) 
          .WithService.Base()); 

Я не могу решить, как я сделал выше. Что дает?

ответ

3

Дать ответ, так как это может быть слишком длинным (и codeful) для комментария.

Учитывая следующий код:

public interface IGenericRepository<T> {} 
public abstract class GenericRepository<T> : IGenericRepository<T> where T : class {} 
public class AGenericRepository<T> : GenericRepository<T> where T : class {} 
public class AInstance: AGenericRepository<string>{} 

эта регистрация отлично работает для меня:

var container = new WindsorContainer(); 
container.Register(Classes.FromThisAssembly().BasedOn(typeof (GenericRepository<>)).WithServiceBase()); 
var result = container.Resolve<GenericRepository<string>>(); 

У меня есть ощущение, что мы недостающую информацию относительно того, что регистрируются классы.


EDIT: в предлагаемом коде, очевидно, абстрактный базовый класс действует как промежуток остановки, чтобы определить, что такое базовая услуга. При использовании после регистрации разрешения работы:

var container = new WindsorContainer(); 
container.Register(Classes.FromThisAssembly().BasedOn(typeof (GenericRepository<>)).WithServiceAllInterfaces()); 
var result = container.Resolve<IGenericRepository<string>>(); 

Однако разрешение против GenericRepository, кажется, не работает, потому что он не зарегистрирован в качестве компонента разрешения в замке. Если вы хотите самостоятельно зарегистрировать компоненты, вы можете описать их напрямую:

+0

Почему у вас есть класс AInstance? Удалите этот класс и сообщите нам, если вы все еще можете решить проблему. –

+0

Поскольку вы не можете разрешить компонент, который не имеет реализации. Но теперь понятно, к чему вы клоните. Я удалю этот ответ, если не могу его обогатить. – samy

+0

Реализация класса AGenericRepository обеспечивает реализацию для любого закрытого типа, такого как AGenericRepository . Мой вопрос также включал одну-единственную регистрацию и разрешающий код, который работает. Я спрашиваю, есть ли способ зарегистрироваться по соглашению в этом сценарии. –

3

DefaultInterfaces() только регистрирует интерфейсы с соответствующим именем.

Соответствующие имена означают, что класс реализации содержит в своем имени имя интерфейса (без I на передней панели).

http://docs.castleproject.org/Windsor.Registering-components-by-conventions.ashx

+0

Хорошо поймать. Это была просто ошибка, посреди меня, я пробую разные вещи. Я изначально использовал Base(), но WithService.Base() тоже не работает. –

+0

Да, похоже, там проблема, когда вы используете абстрактный класс, а не интерфейс. Но почему вы хотите использовать соглашения? У вас есть один открытый общий сервис и одна открытая общая реализация. Ваш первый подход к регистрации работает отлично. –

+0

Было бы неплохо, если бы я мог зарегистрироваться по соглашению, потому что, если у меня есть общие реализации для NHibernate, EntityFrameWork, Memory (для тестирования) и т. Д., Они все будут зарегистрированы автоматически по мере их добавления. Было бы неплохо узнать, что это возможно. Кроме того, это всего лишь одна ситуация. Что, если в другой ситуации есть потенциал, чтобы иметь немало реализаций? Это основа для регистрации по Конвенции. –