Some of my classes have a constructor similar to the following:
public class MyComponent : BaseComponent, IMyComponent
{
public MyComponent(IPostRepository postsRepo, int postId, ICollection<string> fileNames)
{
// ...
}
}
IPostRepository
is a volatile dependency, but it can be initialized at application start. The postId and fileNames arguments are only known at run time.
How can I use Castle Windsor (3.2.0, if it matters) to handle the injection of the IPostRepository
dependency while still allowing run-time constructor parameters?
(While one approach might be to refactor MyComponent
, this would be a significant undertaking as many other portions of the code already refer to MyComponent
.)
Here's where I've gotten so far: I think that I need to create a MyComponentFactory
. The interface of MyComponentFactory
would look like
public interface IMyComponentFactory
{
IMyComponent Create(params object[] args);
}
This IMyComponentFactory
would be injected into the layer above (the controller in my case) like so:
public class MyController : Controller
{
private IMyComponentFactory _myComponentFactory;
public MyController(IMyComponentFactory myComponentFactory)
{
_myComponentFactory = myComponentFactory;
}
public ActionResult MyAction(int postId)
{
List<string> fileNames = new List<string>();
// ...
// Creates a new instance of the resolved IMyComponent with the IPostRepository that was injected into IMyComponentFactory and the run time parameters.
IMyComponent myComponent = _myComponentFactory.Create(postId, fileNames);
// Now do stuff with myComponent
return View();
}
}
Finally, I have attempted to let Castle Windsor create the factory implementation by registering my IMyComponentFactory
in the composition root like so:
// Add Factory facility
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IMyComponentFactory>().AsFactory());
Doing this results in a DependencyResolverException
with a message of
Could not resolve non-optional dependency for 'Playground.Examples.Components.MyComponent' (Playground.Examples.Components.MyComponent). Parameter 'postId' type 'System.Int32'
The error makes sense, and I'm guessing that I need to create a custom implementation of IMyComponentFactory
, but I'm not sure how to go about it.