В своей статье хочу рассмотреть пример неправильного, на мой взгляд, использования Dependency Injection принципа и попробовать отыскать мотивацию для других разработчиков команды (а может и кому еще сгодится) писать новый код лучше, а также по мере сталкивания в рамках рабочих активностей с чужим кодом, написанным неграмотным образом, делать рефакторинг.
Итак, суть проблемы. На проекте мы используем OData WebApi и все контроллеры наследуются от базового, используют метод GetService из базового класса который вытягивает зависимости через статический класс ApiControllerScopeContextMediator.
А в Global.asax конфигурируем подтягивание зависимостей для OData через StructureMap:
Во всех action у контроллеров повсеместно используется метод GetService, как, например, здесь:
Но почему? Ведь можно было бы просто использовать constructor injection:
Так что же все-таки: «Таити, Таити» (Constructor Injection) или «нас и здесь неплохо кормят» (GetService)?
Итак, суть проблемы. На проекте мы используем OData WebApi и все контроллеры наследуются от базового, используют метод GetService из базового класса который вытягивает зависимости через статический класс ApiControllerScopeContextMediator.
public abstract class ODataControllerBase : ODataController
{
protected T GetService<T>()
{
return ApiControllerScopeContextMediator.GetService<T>(this);
}
}
internal static class ApiControllerScopeContextMediator
{
internal static T GetService<T>(ApiController controller)
{
return (T) controller.Configuration.DependencyResolver.GetService(typeof (T));
}
}
А в Global.asax конфигурируем подтягивание зависимостей для OData через StructureMap:
GlobalConfiguration.Configuration.DependencyResolver = new StructureMapDependencyResolver(container);
Во всех action у контроллеров повсеместно используется метод GetService, как, например, здесь:
public class DisconnectedAppsController : ODataControllerBase
{
public IHttpActionResult Get()
{
var query = GetService<IQuery<IQueryable<DisconnectedAppDomain>, DisconnectedAppFilter>>();
}
}
Но почему? Ведь можно было бы просто использовать constructor injection:
public DisconnectedAppsController(IQuery<IQueryable<DisconnectedAppDomain>, DisconnectedAppFilter> query){
_query = query;
}
Так что же все-таки: «Таити, Таити» (Constructor Injection) или «нас и здесь неплохо кормят» (GetService)?