Виндзорский замок Инъекционные свойства построенного объекта - PullRequest
5 голосов
/ 12 мая 2009

Некоторые контейнеры для внедрения зависимостей позволяют вам внедрять настроенные сервисы в уже созданный объект.

Может ли это быть достигнуто с помощью Windsor, принимая во внимание какие-либо сервисные зависимости, которые могут быть на целевом объекте?

Ответы [ 3 ]

9 голосов
/ 08 июня 2011

Это старый вопрос, но Google недавно привел меня сюда, поэтому я поделился своим решением, чтобы оно не помогло кому-то найти что-то вроде метода BuildUp для WindMor в StructureMap.

Я обнаружил, что могу сам относительно легко добавить эту функцию. Вот пример, который просто внедряет зависимости в объект, где он находит нулевое свойство типа интерфейса. Конечно, вы можете расширить концепцию для поиска определенного атрибута и т. Д .:

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);
            }
        }
    }
}

Вот простой модульный тест для этого метода:

[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
    {
    }
}
5 голосов
/ 12 мая 2009

Нет, не может.

1 голос
/ 12 мая 2009

Как сказал Кшиштоф, официального решения для этого не существует. Возможно, вы захотите попробовать этот обходной путь , хотя.

Лично я считаю, что нужно сделать это с запахом кода. Если это ваш код, почему он не зарегистрирован в контейнере? Если это не ваш код, напишите для него фабрику / адаптер / и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...