1
votes

I need to use Castle Windsor to automatically resolve some kind of services that are dependent on another parameter of the constructor where they are referenced. Here is a simple example:

the service I want to resolve is:

public interface IDependentParameter
{
   IValue Value;

   object Something;
}

Implemented by :

public class DependentParameter : IDependentParameter
{
   public DependentParameter(IValue value)
   {
      Value = value;
   }

   public IValue Value;

   public object Something;
}

IValue is another service that I can inject manually into the constructor

My dependant class looks like:

public class DependentClass : IDependentClass 
{
   IValue Value {get; protected set;}
   IDependentParameter DependentParameter{get; protected set;}

   public DependentClass (IValue value, IDependentParameter dependentParameter)
   {
     Value = value;
     DependentParameter= dependentParameter;

   }
}

The resolution code should be like:

var dependant = container.Resolve<IDependantClass>(new { value = knownValue });

On other posts, I saw solutions referencing AbstractFactory or TypedFactoryFacility. but the drawbacks I see on that solutions are:

  • Unable to know just by looking at DependentClass constructor which services are needed (we will see just the factory service).
  • How to implement the factory so that it can reference the castle windsor container to resolve IDependentParameter and not the new keyword. I absolutly need an instanciation using castle because I'm creating dynamic proxies instead.
1
Why you are not registering an implementation for IValue into the container as well? Which scope/lifestyle do you need for it?Crixo
IValue is a runtime value which can not be defined on registration time.enenkey
If that's a runtime value... TypedFactoryFacility should be the way to go. Have a look to the tutorial on windosr wiki: using ComponentSelector among your TypedFactory you have access to the container without leaking the container into your bizlogicCrixo
Thanks for your answer. Actually I think that TypedFactoryFacility would be a convenient way, but I need to have more control on the factory. especially for specifying additional dependencies (that can be used by the factory)enenkey

1 Answers

0
votes

If I understand well, you would like Castle Windsor to guess that he have to use the given instance of Value when resolving DependentClass AND DependentParameter.

With the current version of Castle, the construction of Dependencies does not use the initial argument list. So you have to wait until Castle implement this behavior (I don't even know if it will be done one day).

What you could do if you're not patient enough, is to use a little trick. In fact there is a way in Castle to keep the context (and so the argument list) when resolving Dependencies, but it depends on the Dependency herself.

As soon as the Dependency is Generic, the context will be conserved.

For exemple in your case you could do the following change :

public class DependentParameter<T> : IDependentParameter where T : IValue
{
   public DependentParameter(T value)
   {
      Value = value;
   }

   public T Value;

   public object Something;
}

I know it is not an ideal way to do, but it makes the trick :)