Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windsor castle Injecting properties of constructed object

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?

like image 931
PhilHoy Avatar asked May 12 '09 09:05

PhilHoy


2 Answers

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
    {
    }
}
like image 172
Tana Isaac Avatar answered Sep 18 '22 14:09

Tana Isaac


No, it can't.

like image 27
Krzysztof Kozmic Avatar answered Sep 20 '22 14:09

Krzysztof Kozmic