passing part of constructor parameters to castle windsor container
Asked Answered
B

2

9

I have constructor

Foo(IColor c , int someNumber)

and I know the some number only during the run time, and I want to call this constructor during the resolving and to pass someNumber value and the IColor to be resolved autocratically.

Something like this:

container.Resolve<IFoo>(someNumber);

Is it possible to be done ?

Buchholz answered 30/7, 2012 at 17:38 Comment(0)
D
10

Yes, pass the constructor arguments in an instance of an anonymous type; the property names must match the constructor parameter names:

IColor desiredColor = //whatever
int desiredNumber = //whatever else
IFoo foo = container.Resolve<IFoo>(new { c = desiredColor, somenumber = desiredArgumentValue });

If you are using an older version of C# that does not support anonymous types (or even if you're not), you can do the same with a dictionary:

IColor desiredColor = //whatever
int desiredNumber = //whatever
Dictionary<string, object> arguments = new Dictionary<string, object>();
arguments.Add("c", desiredColor);
arguments.Add("somenumber", desiredNumber);
IFoo foo = container.Resolve<IFoo>(arguments);
Drying answered 30/7, 2012 at 17:57 Comment(2)
What about the IColor parameter?Galangal
@Galangal I've edited the answer to include a corresponding argument.Drying
J
18

You should prefer Typed Factory instead of using container like service locator. Just define factory interface:

public interface IFooFactory {
    IFoo Create(int somenumber);
}

and register it as typed factory:

container.Register(Component.For<IFooFactory>().AsFactory());

Then use dependency injection to inject factory and use it:

var foo = fooFactory.Create(desiredArgumentValue);

For more info read Windsor documentation

Jenness answered 31/7, 2012 at 6:52 Comment(2)
Nice answer. Does it mean that if I use this factory, I always have to remember to release the object after using it? The document says "Remember that by default all components in Windsor are singletons and that using default release policy container keeps reference to all components, even transient ones. That's why it's important to release components via typed factory. Also pay attention to lifetime you assign to components resolved via the facility. "Teena
Yes, it is best practice. You can define void Destroy(IFoo component) method on factory interface for this purpose, or implement IDisposable in your component and dispose it. Then it will be released.Conveyancing
D
10

Yes, pass the constructor arguments in an instance of an anonymous type; the property names must match the constructor parameter names:

IColor desiredColor = //whatever
int desiredNumber = //whatever else
IFoo foo = container.Resolve<IFoo>(new { c = desiredColor, somenumber = desiredArgumentValue });

If you are using an older version of C# that does not support anonymous types (or even if you're not), you can do the same with a dictionary:

IColor desiredColor = //whatever
int desiredNumber = //whatever
Dictionary<string, object> arguments = new Dictionary<string, object>();
arguments.Add("c", desiredColor);
arguments.Add("somenumber", desiredNumber);
IFoo foo = container.Resolve<IFoo>(arguments);
Drying answered 30/7, 2012 at 17:57 Comment(2)
What about the IColor parameter?Galangal
@Galangal I've edited the answer to include a corresponding argument.Drying

© 2022 - 2024 — McMap. All rights reserved.