我无法使用带有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
我已经检查了样品,它们与这种方法不同。请你告诉我我做错了什么?
感谢。
答案 0 :(得分:1)
Typhoon是一个依赖注入容器,这意味着它不会对你的类进行监视,调配或其他方式。因此,要获取注入依赖项的类的实例,我们必须询问Typhoon。
为什么不使用故事板?
当使用plist集成时,Typhoon会根据UIStoryboard注册TyphoonStoryboard以根据故事板中的定义发出实例 - 就像普通的故事板一样,具有注入依赖关系的额外好处。
在其他地方,为了获取注入了依赖项的实例,我们使用汇编接口,并询问Typhoon。
解决方案步骤:
在程序集中添加ViewControllerB的定义。 (在Objective-C中,如果您愿意,也可以使用自动注入宏)。
- (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的按钮操作:
ViewControllerC *viewControllerC = self.assembly.viewControllerC
[self.navigationController pushViewController:viewControllerC animated:YES];
现在我的应用程序类依赖于我的TyphoonAssembly,如果我不想要这个怎么办?
所有Typhoon程序集都可以由协议支持,因此您的应用程序只能看到实例提供程序,而不是Typhoon。如果您曾希望从Typhoon迁移,只需提供该协议的替代实现 - 您仍将拥有强大的架构。
答案 1 :(得分:0)
所以,我必须首先向我的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];
,所以不确定哪种方法更好。
无论如何,我想我必须打电话给新人并至少激活一次。
感谢。