Castle Windsor passing constructor parameters
Asked Answered
A

1

16

I have an IAddress class with a few properties. I then have a concrete type that implements this interface. This concrete type has a couple of different constructors I could use. How can I pass parameter values to one of these constructors at run-time? I cannot use the config file as I will be reusing this concrete type multiple times and each time the parameter values will be different.

IWindsorContainer container = new WindsorContainer(new XmlInterpreter());
IAddress address = container.Resolve<IAddress>();


public interface IAddress
{
    string Address1 { get; set; }
    string Address2 { get; set; }
    string City { get; set; }
    string State { get; set; }
    string ZipCode { get; set; }
}


class TestAddress : IAddress
{

    private string _address1;
    private string _address2;
    private string _city;
    private string _countyName;
    private string _state;
    private string _zipCode;

    public string Address1
    {
        get { return _address1; }
        set { _address1 = value; }
    }

    public string Address2
    {
        get { return _address2; }
        set { _address2 = value; }
    }

    public string City
    {
        get { return _city; }
        set { _city = value; }
    }

    public string State
    {
        get { return _state; }
        set { _state = value; }
    }

    public string ZipCode
    {
        get { return _zipCode; }
        set { _zipCode = value; }
    }

    public string CountyName
    {
        get { return _countyName; }
        set { _countyName = value; }
    }


    public MelissaAddress(string address1, string address2, string city, string state, string zipcode)
    {
        Address1 = address1;
        Address2 = address2;
        City = city;
        State = state;
        ZipCode = zipcode;
    }

    public MelissaAddress(string address1, string address2, string zipcode) : this(address1, address2, null, null, zipcode)
    { }

    public MelissaAddress(string address1, string address2, string city, string state) : this(address1, address2, city, state, null)
    { }
}
Ander answered 24/4, 2009 at 2:0 Comment(3)
Is this your actual code or just some sample? It looks like you're using the container as a replacement for new().Wives
do you want to specify parameters at registration-time or resolution-time?Wives
I'd like to specify the parameters at resolution time. If I need 2 address classes each with a different address then I'd like to pass the values to each class in the constructor.Ander
W
24

You can use Resolve(object argumentsAsAnonymousType) or Resolve(IDictionary arguments). Windsor will select the best matching constructor.

For example this will select your second constructor:

container.Resolve<IAddress>(
    new {address1 = "myaddress1", address2 = "myaddress2", zipcode = "myzipcode"}
)
Wives answered 24/4, 2009 at 2:53 Comment(6)
You might also consider wrapping this invocation in a factory, or if you get addresses from elsewhere - using ISubDependencyResolver to provide them to the container, instead of passing them from the call site (if this is an option)Lycanthropy
Hmm, interesting. What if you're using the MS CommonServiceLocator rather than directly calling into Castle Windsor, though? Some sort of facility?Raynor
Is it possible to just pass some arguments and have other arguments in the same constructor, resolved by castle windsor?Marisolmarissa
@SideFX: no, but what you're probably asking about is done at registration time, not at resolution-time. Post a new question with all relevant details.Wives
SideFX, Mauricio: Actually what SideFX asks is perfectly possible as I'm doing it right now. Whatever you don't provide castle will try to resolve for you.Ladylike
And if in the caller I don't have any reference to the container? (I'm in a DLL which is loaded somehow by windsor). Where the the operation of Resolve is called I still don't have the parameters to pass to the method..Flippant

© 2022 - 2024 — McMap. All rights reserved.