开发者

How to force the order of Installer Execution

I have been building a new .NET solu­tion with Cas­tle per­form­ing my DI.

Its now at the stage where i would like to con­trol the order in which my installers run. I have built indi­vid­ual classes which implement IWind­sorIn­staller to han­dle my core types — eg IRepos­i­tory, IMap­per and ISer­vice to name a few.

I see that its suggested i implement my own Installer­Fac­tory (guessing i just override Select) in this class.

Then use this new factory in my call to:

FromAssembly.InDirectory(new AssemblyFilter("bin loca­tion")); 

My ques­tion — when over­rid­ing the save method — what is the best way to force the orde开发者_JS百科r of my installers.


I know its already solved but I couldn't find any example on how to actually implement the InstallerFactory so here's a solution if anyone is googling for it.

How to use:

[InstallerPriority(0)]
    public class ImportantInstallerToRunFirst : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store)
        {
            // do registrations
        }
    }

Just add the InstallerPriority attribute with a priority to your "install-order-sensitive" classes. Installers will be sorted by ascending. Installers without priority will default to 100.

How to implement:

public class WindsorBootstrap : InstallerFactory
    {

        public override IEnumerable<Type> Select(IEnumerable<Type> installerTypes)
        {
            var retval =  installerTypes.OrderBy(x => this.GetPriority(x));
            return retval;
        }

        private int GetPriority(Type type)
        {
            var attribute = type.GetCustomAttributes(typeof(InstallerPriorityAttribute), false).FirstOrDefault() as InstallerPriorityAttribute;
            return attribute != null ? attribute.Priority : InstallerPriorityAttribute.DefaultPriority;
        }

    }


[AttributeUsage(AttributeTargets.Class)]
    public sealed class InstallerPriorityAttribute : Attribute
    {
        public const int DefaultPriority = 100;

        public int Priority { get; private set; }
        public InstallerPriorityAttribute(int priority)
        {
            this.Priority = priority;
        }
    }

When starting application, global.asax etc:

container.Install(FromAssembly.This(new WindsorBootstrap()));


You can call your installers in the order they need to be instantiated in Global.asax.cs or e.g. in a Bootstrapper class, which is called from Global.asax.cs.

        IWindsorContainer container = new WindsorContainer()
            .Install(                    
                new LoggerInstaller()           // No dependencies
                , new PersistenceInstaller()    // --""--
                , new RepositoriesInstaller()   // Depends on Persistence
                , new ServicesInstaller()       // Depends on Repositories
                , new ControllersInstaller()    // Depends on Services
            );

They are instantiated in this order, and you can add a breakpoint after and check the container for "Potentially misconfigured components".

If there are any, check their Status->details, if not, it's the correct order.

This solution is quick and easy, the documentation mentions using a InstallerFactory Class for tighter control over your installers so if you have a ton of installers the other solution may fit better. (Using code as convention should not require tons of installers?)

http://docs.castleproject.org/Windsor.Installers.ashx#codeInstallerFactorycode_class_4


In the end i had to use InstallerFactory and implement the ordering rules as suggested previously by returning the IEnumerable<Type> with my specific order

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜