Skip to content

Внедрение зависимостей

Igor Polyakov edited this page Mar 8, 2018 · 2 revisions

Введение

Внедрение зависимостей доступно на уровне свойст аспектов с использованием атрибута [InjectDependency]. Для корректной работы механизма рекомендуется использовать библиотеку плюс плагин для одного из поддерживаемых сторонних DI фреймворков.

Ограничения применения

Свойства, используемые для внедрения зависимостей должны быть публичными и иметь публичный setter.

Пример

public class MyAspect : MethodBoundaryAspect 
{
    [InjectDependency]
    public IMyService MyService { get; set; }

    public override void OnEntry(IInvocationPipeline pipeline)
    {
        MyService.DoSomething();
    }
}

Настройки

Дополнительно механизм внедрения зависимостей можно конфигурировать точечно через установку свойств атрибута. Для изменения доступны следующие свойства:

  • Transparent (bool) - устанавливает признак того, что зависимость должна быть получена в прозрачном виде. Под прозрачной зависимостью понимается реализация запрашиваемого компонента без обвязки из аспектов. То есть будет получена зависимость в том виде, в каком она была изначально зарегистрирована в DI контейнер. При этом динамического проксирования вызовов методов не произойдет. Это может быть полезно, когда внутри аспекта необходимо обратиться к методу сервиса, который так же помечен некоторым аспектом, чтобы избежать дедлока на вызовы;

  • ServiceKey (string) - ключ именованной зависимости. Позволяет получить экземпляр именованного компонента, если DI фреймворк поддерживает именованную регистрацию компонентов.

Подводные камни

  • При использовании Castle.Windsor установка признака Transparent на зависимости в true помимо отмены применения обвязки из аспектов так же отменит применение всех установленных перехватчиков (Interceptor) при регистрации;
  • Фреймворк SimpleInjector не поддерживает регистрацию именованных зависимостей. Поэтому установка ServiceKey на зависимость приведет к исключению в рантайме
  • Зависимости инициализируются из контейнера каждый раз при срабатывании аспекта на метод
  • Управление disposable зависимостями отдается на сторону DI фреймворка. То есть, при повторной инициализации зависимости Dispose() у установленного ранее экземпляра сервиса не вызывается.