Упорядоченное разрешение шрифтов из Castle Windsor AllTypes

У меня есть группа классов, которые реализуют интерфейс для запуска моих приложений. Вот регистрационный код:

private static void ConfigureContainer()
{
    var container = new WindsorContainer();

    container.Register(AllTypes.Of<IStartupTask>()
             .FromAssembly(Assembly.GetExecutingAssembly()))
    ...

    var serviceLocator = container.Resolve<IServiceLocator>();
    ServiceLocator.SetLocatorProvider(() => serviceLocator);
}

Чтобы получить задачи, я использую это, и оно работает так, как ожидалось:

public static void Run()
{
    var tasks = ServiceLocator.Current.GetAllInstances<IStartupTask>();

    foreach (var task in tasks)
    {
       task.Execute();
    }
}

Вот моя проблема: у меня есть одна задача, которая зависит от запуска другой. Существует задача InitializeDatabase, которую необходимо выполнить перед задачей PopulateDatabse. Есть также куча других задач, которые выполняются, и я бы не стал разделять задачу InitializeDatabase, если есть какая-то конфигурация Castle, которая позволит мне упорядочить разрешение типов. Я не хочу указывать полный порядок разрешаемых типов, поскольку это противоречит цели автоматической регистрации, просто InitializeDatabase является первым или PopulateDatabase последним.

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


person Steven Lyons    schedule 08.05.2009    source источник
comment
Почему вы используете Common Service Locator?   -  person Mauricio Scheffer    schedule 09.05.2009
comment
Я экспериментировал с некоторыми другими инструментами и еще не вынул его. Я скопировал фрагменты из своего кода и не хотел ошибиться с синтаксисом Castle в вопросе. Большое спасибо за ваш ответ, я попробую.   -  person Steven Lyons    schedule 09.05.2009


Ответы (2)


Вот один из способов сделать это, он может быть не очень красивым, но он работает:

[AttributeUsage(AttributeTargets.Class)]
public class FirstAttribute: Attribute {}
public interface IService {}
public class ThirdService : IService { }
[First]
public class FirstService : IService { }
public class SecondService: IService {}

[Test]
public void WindsorOrder() {
    var container = new WindsorContainer();

    container.Register(AllTypes.Of<IService>()
        .FromAssembly(Assembly.GetExecutingAssembly()));

    var intf = container.ResolveAll<IService>()
        .OrderByDescending(i => i.GetType().GetCustomAttributes(typeof(FirstAttribute), true).Length)
        .ToArray();
    Assert.IsInstanceOfType(typeof(FirstService), intf[0]);
}

Если вы удалите [First] из FirstService, первым будет ThirdService, и тест завершится неудачно.

person Mauricio Scheffer    schedule 09.05.2009

Используйте HandlerSelector для этого

person Krzysztof Kozmic    schedule 11.05.2009
comment
Спасибо за указатель. Я посмотрел на HandlerSelector, но не понял, как его использовать в этом случае. HandlerSelector.SelectHandler() вызывается для каждой реализации IStartupTask, поэтому я не уверен, как заказать оттуда разрешения службы. Я неправильно использую HandleSelector? - person Steven Lyons; 11.05.2009