台风不注入财产(没有故事板)
我无法通过initWithNibName:bundle:
使用XIB将属性注入视图控制器initWithNibName:bundle:
例:
这是我的大会:
@implementation AppAssembly - (ViewControllerC *)viewControllerC { return [TyphoonDefinition withClass:[ViewControllerC class] configuration:^(TyphoonDefinition *definition) { [definition injectProperty:@selector(name) with:@"Injected string"]; }]; } @end
ViewControllerA代码:
@implementation ViewControllerA - (IBAction)buttonAction:(id)sender { ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNibName:@"ViewControllerB" bundle:nil]; [self.navigationController pushViewController:viewControllerB animated:YES]; } @end
ViewControllerB代码:
@implementation ViewControllerB - (IBAction)buttonAction:(id)sender { ViewControllerC *viewControllerC = [[ViewControllerC alloc] initWithNibName:@"ViewControllerC" bundle:nil]; [self.navigationController pushViewController:viewControllerC animated:YES]; } @end
ViewControllerC代码:
@interface ViewControllerC : UIViewController @property (copy, nonatomic) NSString *name; @end @implementation ViewControllerC - (void)viewDidLoad { [super viewDidLoad]; // Why is this not being injected? self.title = self.name; } @end
AppDelegate代码:
@implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ViewControllerA *rootViewController = [[ViewControllerA alloc] initWithNibName:@"ViewControllerA" bundle:nil]; UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.rootViewController = navigationController; [self.window makeKeyAndVisible]; return YES; } @end
我已经检查过这些样本,并且与这种方法不同。 请你能告诉我我做错了什么?
谢谢。
台风是一个dependency injection的容器 ,这意味着它没有仪器,swizzle或其他触摸你的课程。 因此,为了得到一个注入了依赖关系的类的实例, 我们必须问Typhoon。
为什么不为故事板?
当使用plist集成时,Typhoon会根据故事板中的定义将TyphoonStoryboard注册到UIStoryboard的位置来发出实例 – 就像一个正常的故事板一样工作,同时注入依赖关系。
在其他地方,为了获得注入依赖关系的实例,我们使用汇编接口,并问Typhoon。
解决scheme步骤
在您的程序集中为ViewControllerB添加一个定义。 (在Objective-C中,如果你愿意,你也可以使用自动注入macros)。
- (ViewControllerB *)viewControllerB { return [TyphoonDefinition withClass:[ViewControllerB class] configuration:^(TyphoonDefinition *definition) { [definition useInitializer:@selector(initWithNibName:bundle:) parameters:^(TyphoonMethod *initializer) { [initializer injectParameterWith:@"ViewControllerB"]; [initializer injectParameterWith:[NSBundle mainBundle]]; }]; [definition injectProperty:@selector(assembly) with:self]; }]; }
将属性添加到ViewControllerB:
//Start with this, next task is to back this with a protocol @property(nonatomic, strong) AppAssembly *assembly;
现在改变实例化ViewControllerC的button动作:
ViewControllerC *viewControllerC = self.assembly.viewControllerC [self.navigationController pushViewController:viewControllerC animated:YES];
现在我的应用程序类取决于我的TyphoonAssembly,如果我不想要这个?
所有的台风组件都可以由一个协议来支持,这样你的应用程序只能看见一个实例提供者,而不是台风。 如果你想从台风迁移,只需提供一个替代实施的协议 – 你仍然会有一个强大的架构。
所以,我不得不先问我的AppAssembly的一个实例viewControllerB与注入的程序集,然后我能够使用它来获取viewControllerC的一个实例。
AppAssembly代码:
- (ViewControllerB *)viewControllerB { return [TyphoonDefinition withClass:[ViewControllerB class] configuration:^(TyphoonDefinition *definition) { [definition useInitializer:@selector(initWithNibName:bundle:) parameters:^(TyphoonMethod *initializer) { [initializer injectParameterWith:@"ViewControllerB"]; [initializer injectParameterWith:nil]; }]; [definition injectProperty:@selector(assembly) with:self]; }]; } - (ViewControllerC *)viewControllerC { return [TyphoonDefinition withClass:[ViewControllerC class] configuration:^(TyphoonDefinition *definition) { [definition useInitializer:@selector(initWithNibName:bundle:) parameters:^(TyphoonMethod *initializer) { [initializer injectParameterWith:@"ViewControllerC"]; [initializer injectParameterWith:nil]; }]; [definition injectProperty:@selector(name) with:@"Injected string"]; }]; }
ViewControllerA代码:
@implementation ViewControllerA - (IBAction)buttonAction:(id)sender { ViewControllerB *viewControllerB = [[[AppAssembly new] activate] viewControllerB]; [self.navigationController pushViewController:viewControllerB animated:YES]; } @end
ViewControllerB代码:
@implementation ViewControllerB - (IBAction)buttonAction:(id)sender { ViewControllerC *viewControllerC = [self.assembly viewControllerC]; [self.navigationController pushViewController:viewControllerC animated:YES]; } @end
ViewControllerC代码:
@implementation ViewControllerC - (void)viewDidLoad { [super viewDidLoad]; self.title = self.name; } @end
正如你所看到的,我必须这样做: ViewControllerB *viewControllerB = [[[AppAssembly new] activate] viewControllerB];
不知道是否有另一种方式。 因为这样做,我能够在ViewControllerB中注入程序集,并且让我这样做: ViewControllerC *viewControllerC = [self.assembly viewControllerC];
不过,我注意到我也可以做ViewControllerC *viewControllerC = [[[AppAssembly new] activate] viewControllerC];
,所以不确定哪个更好的方法是。 无论如何,我想我不得不打电话给至less一次。
谢谢。