Кто должен владеть зависимыми объектами Injected в приложениях iOS?

Это, вероятно, фундаментальный вопрос для опытного разработчика iOS, но, исходя из фона Java, в котором у нас много положительных эффектов Dependency Injection (DI) (т.е. Spring), у меня возникли проблемы с выяснением того, кто должен владеть объекты DI. К сожалению, я нахожу, что создаю группу синглтонов, которая становится довольно неприятной для управления.

Например, мы имеем несколько Configuration, к которым хотели бы обращаться другие классы. В настоящее время у нас есть только один экземпляр конфигурации для конфигурации, что затрудняет тестирование. Технически мы преодолеваем эту проблему, используя метод swizzling в OCMock.

В Java/ Spring существует некоторый контейнер, который создает/владеет этими объектами. В iOS я думаю, что ближайшими вещами, которые у меня есть к контейнеру, являются UIApplication и UIApplicationDelegate. Имеет ли смысл эти вещи создавать/владеть этими объектами, которые в конечном итоге будут введены в другие объекты?

Если да, то какая подходящая стратегия для доступа к этим объектам? Например, создайте категорию в UIApplication или UIApplicationDelegate для доступа к этим объектам, таким как: [[UIApplication sharedApplication] configuration] или [[[UIApplication sharedApplication] delegate] configuration]

Ответ 1

Действительно, DI не похоже на то, что люди обычно используют в iOS, например, на Java или С#.

Лично я склонен создавать свой собственный синглтон под названием Application, который содержит все службы и информацию для приложения. Таким образом, я получаю простоту простого синглета, не привязанного к iOS (хотя obj-c не может использоваться практически нигде). Поэтому в моих приложениях я обычно:

[[Application sharedInstance] configuration]
[[Application sharedInstance] authService]

Таким образом, единственным классом, который должен быть singleton, является Application one (не связанный с UIApplication), и он создает все службы в методе init.

Ответ 2

Я начинаю оценку рамки Objective-C DI под названием Objection. Это вдохновило Google Guice на Java.

Пример использования с возражения README

@class Engine, Brakes;

@interface Car : NSObject
{
  Engine *engine;
  Brakes *brakes;
  BOOL awake;  
}

// Will be filled in by objection
@property(nonatomic, retain) Engine *engine;
// Will be filled in by objection
@property(nonatomic, retain) Brakes *brakes;
@property(nonatomic) BOOL awake;

@implementation Car
objection_register(Car)
objection_requires(@"engine", @"brakes")
@synthesize engine, brakes, awake;
@end