Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Castle Windsor: How to specify a constructor parameter from code?

Say I have the following class

MyComponent : IMyComponent {
  public MyComponent(int start_at) {...}
}

I can register an instance of it with castle windsor via xml as follows

<component id="sample"  service="NS.IMyComponent, WindsorSample" type="NS.MyComponent, WindsorSample">  
  <parameters>  
    <start_at>1</start_at >  
  </parameters>  
</component>  

How would I go about doing the exact same thing but in code? (Notice, the constructor parameter)

like image 805
George Mauer Avatar asked Sep 17 '08 21:09

George Mauer


3 Answers

Edit: Used the answers below code with the Fluent Interface :)

namespace WindsorSample
{
    using Castle.MicroKernel.Registration;
    using Castle.Windsor;
    using NUnit.Framework;
    using NUnit.Framework.SyntaxHelpers;

    public class MyComponent : IMyComponent
    {
        public MyComponent(int start_at)
        {
            this.Value = start_at;
        }

        public int Value { get; private set; }
    }

    public interface IMyComponent
    {
        int Value { get; }
    }

    [TestFixture]
    public class ConcreteImplFixture
    {
        [Test]
        void ResolvingConcreteImplShouldInitialiseValue()
        {
            IWindsorContainer container = new WindsorContainer();

            container.Register(
                Component.For<IMyComponent>()
                .ImplementedBy<MyComponent>()
                .Parameters(Parameter.ForKey("start_at").Eq("1")));

            Assert.That(container.Resolve<IMyComponent>().Value, Is.EqualTo(1));
        }

    }
}
like image 75
Chris Canal Avatar answered Oct 20 '22 22:10

Chris Canal


Try this

int start_at = 1; 
container.Register(Component.For().DependsOn(dependency: Dependency.OnValue(start_at)));
like image 2
user2964808 Avatar answered Oct 20 '22 21:10

user2964808


Have you considered using Binsor to configure your container? Rather than verbose and clumsy XML you can configure Windsor using a Boo based DSL. Here's what your config will look like:

component IMyComponent, MyComponent:
   start_at = 1

The advantage is that you have a malleable config file but avoid the problems with XML. Also you don't have to recompile to change your config as you would if you configured the container in code.

There's also plenty of helper methods that enable zero friction configuration:

  for type in Assembly.Load("MyApp").GetTypes():
    continue unless type.NameSpace == "MyApp.Services"
    continue if type.IsInterface or type.IsAbstract or type.GetInterfaces().Length == 0
    component type.GetInterfaces()[0], type

You can get started with it here.

like image 1
neilb14 Avatar answered Oct 20 '22 22:10

neilb14