5

Some dependency injection containers enable you to inject configured services into an already constructed object.

Can this be achieved using Windsor, whilst taking account of any service dependencies there may be on the target object?

PhilHoy
  • 1,613
  • 1
  • 12
  • 20

3 Answers3

9

This is an old question but Google led me here recently so thought I would share my solution lest it help someone looking for something like StructureMap's BuildUp method for Windsor.

I found that I could add this functionality myself relatively easily. Here is an example which just injects dependencies into an object where it finds a null Interface-typed property. You could extend the concept further of course to look for a particular attribute etc:

public static void InjectDependencies(this object obj, IWindsorContainer container)
{
    var type = obj.GetType();
    var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
    foreach (var property in properties)
    {
        if (property.PropertyType.IsInterface)
        {
            var propertyValue = property.GetValue(obj, null);
            if (propertyValue == null)
            {
                var resolvedDependency = container.Resolve(property.PropertyType);
                property.SetValue(obj, resolvedDependency, null);
            }
        }
    }
}

Here is a simple unit test for this method:

[TestFixture]
public class WindsorContainerExtensionsTests
{
    [Test]
    public void InjectDependencies_ShouldPopulateInterfacePropertyOnObject_GivenTheInterfaceIsRegisteredWithTheContainer()
    {
        var container = new WindsorContainer();
        container.Register(Component.For<IService>().ImplementedBy<ServiceImpl>());

        var objectWithDependencies = new SimpleClass();
        objectWithDependencies.InjectDependencies(container);

        Assert.That(objectWithDependencies.Dependency, Is.InstanceOf<ServiceImpl>());
    }

    public class SimpleClass
    {
        public IService Dependency { get; protected set; }
    }

    public interface IService
    {
    }

    public class ServiceImpl : IService
    {
    }
}
Tana Isaac
  • 161
  • 2
  • 3
5

No, it can't.

Krzysztof Kozmic
  • 27,267
  • 12
  • 73
  • 115
1

As Krzysztof said, there is no official solution for this. You might want to try this workaround though.

Personally, I consider having to do this a code smell. If it's your code, why isn't it registered in the container? If it isn't your code, write a factory/adapter/etc for it.

Mauricio Scheffer
  • 98,863
  • 23
  • 192
  • 275
  • I agree - it's a smell. Why do you want to do it in the first place? It's plain wrong. – Krzysztof Kozmic May 12 '09 at 14:47
  • I have a pretty simple case where I need to do this: – Steve Nov 08 '10 at 19:08
  • I create an instance via the container, then at some point I serialize my instance. However I don't want to serialize the dependencies. When I deserialize I need to add the dependencies back into the object. How would I solve this problem using Castle Windsor? – Steve Nov 08 '10 at 19:10
  • @Steve: create a new question explaining your problem **in detail** – Mauricio Scheffer Nov 08 '10 at 19:19
  • done: http://stackoverflow.com/questions/4127724/castle-windsor-dependency-injection-problem-with-serialization – Steve Nov 08 '10 at 20:26