user20943029
user20943029

Reputation: 83

How to register multiple classes using a factor method with Windsor Castle

I have a program that consists of various components, which all need their own set of settings. Because these settings are deserialized from a JSON configuration file, I decided to use a factory method that resolves the "main" settings class and from that class I can then get the settings for the specific component.

Here's my code:

using Castle.MicroKernel.Registration;
using Castle.Windsor;

namespace WindsorRegisterTest
{
    public class ApplicationSettings
    {
        private Component1Settings _component1Settings;
        private Component2Settings _component2Settings;

        public ApplicationSettings()
        {
            _component1Settings = new Component1Settings();  // to be loaded from json
            _component2Settings = new Component2Settings();
        }

        public T GetSettings<T>() where T : ComponentSettingsBase
        {
            if (typeof(T).Equals(typeof(Component1Settings))) return _component1Settings as T;
            if (typeof(T).Equals(typeof(Component2Settings))) return _component2Settings as T;
            return default(T);
        }
    }

    public interface ITestComponent{}
    public abstract class ComponentSettingsBase { }
    public class Component1Settings : ComponentSettingsBase { }
    public class Component2Settings : ComponentSettingsBase { }

    public class Component1 : ITestComponent
    {
        public Component1(Component1Settings settings){}
    }
    public class Component2 : ITestComponent
    {
        public Component2(Component2Settings settings) { }
    }

    public class MainComponent : ITestComponent
    {
        public MainComponent(Component1 comp1, Component2 comp2){}
    }

    public class Program
    {
        static void Main(string[] args) => ConfigureContainer().Resolve<MainComponent>();

        private static IWindsorContainer ConfigureContainer()
        {
            IWindsorContainer container = new WindsorContainer();

            container.Register(Component
                .For<ApplicationSettings>()
                .LifestyleSingleton());

            container.Register(Component
                .For<Component1Settings>()
                .UsingFactoryMethod<Component1Settings>(kernel => 
                   kernel.Resolve<ApplicationSettings>().GetSettings<Component1Settings>()));

            container.Register(Component
                .For<Component2Settings>()
                .UsingFactoryMethod<Component2Settings>(kernel => 
                   kernel.Resolve<ApplicationSettings>().GetSettings<Component2Settings>()));

            container.Register(Classes.FromThisAssembly()
               .BasedOn<ITestComponent>().WithService.Self().Configure(c => c.LifestyleTransient()));

            return container;
        }
    }    
}

This example works, but in my real program I don't have 2 components, I have loads. So is there's a way to register all "subsettings" classes in one go, because they're all derived from ComponentSettingsBase?

I have read about facilities, deriving a class from AbstractFacility and then handeling ComponentRegistered or ComponentModelCreated events. However, I can't work out how to do what I want given the event variables available by those events.

Upvotes: 0

Views: 24

Answers (0)

Related Questions