从Castle Windsor AllTypes订购的类型分辨率

时间:2009-05-08 16:32:01

标签: configuration dependency-injection castle-windsor

我有一组为我的应用程序启动活动实现接口的类。这是注册码:

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是最后一个。

有没有办法在没有指定所有类型的顺序的情况下首先注册哪些类型?

2 个答案:

答案 0 :(得分: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,测试将失败。

答案 1 :(得分:0)

使用HandlerSelector