In some simple cases it may feel like an overkill to create additional
when all you want is to resolve single component. For cases like this Windsor (version 2.5 or newer) lets you take dependency on a
, and the
will callback to the container to provide the instance for you when you invoke it.
There's nothing magical with
-based factories. You use them as regular delegates, while Windsor does all the heavy lifting.
public class UsingDelegate
private Func<IFoo> factory;
public void UsingDelegate(Func<IFoo> fooFactory)
factory = fooFactory;
public void SomeOperation()
var foo = factory();
In this case creating a
does not trigger creation of (potentially expensive to create - think NHibernate's
will only be created when call to
occurs, which may be a log time after
Registering factories (implicitly)
The act of exposing delegate as dependency is enough to instruct the facility that it should provide a factory. This is called implicit registration. It can't be just any delegate though. Similar rules as with
-based factories apply:
- delegate must have a non-
void return type.
- delegate can't have out arguments
The factories registered that way will have transient
Registering factories explicitly
When you register the factory implicitly you give up the ability to configure the factory. If you need some non-default configuration, you can register, and configure the factory explicitly.
Component.For<Func<IFoo>>().AsFactory(c => c.SelectedWith("nonDefaultFactory")));
How dependencies are matched
Dependencies are matched a little differently for
public delegate IFoo FooFactory(IBar bar);
If component registered for service
has dependency named
it will be satisfied with the value passed to the delegate.
If instead the component has dependency named
, it won't find it on the
delegate. It will then go and see if there's any dependency for type
regardless of it's name, and if it finds one, it will use that instead.
Duplicated dependency types are not allowed for
Func<> family of delegates.
When using generic purpose delegate
(any of them) it is not possible to have delegate with duplicated argument types. Since their names are just meaningless
etc, it is not possible to discriminate between arguments in
. In this case use dedicated
type, or better yet -
Releasing components resolved via factory
It is important to remember that if the Release Policy
of your container tracks a component you resolve, the factory will hold a reference to the component as well. This is to let Windsor release the components you resolve via the factory, when the factory itself gets released.
NoTrackingReleasePolicy will not release the factory
Since release policies that do not track components are not able to release them, it's important to use
(which is the default) when using
-based factories to be able to properly release the components resolved via the factory.