Кто должен владеть зависимыми объектами 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