-
Notifications
You must be signed in to change notification settings - Fork 268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support a block-style assembly made of many child assemblies. #92
Comments
+1 |
This is top priority, as the impact is high. |
Fixed in 1.3.6, whch can be installed via CocoaPods |
Oops. Stop the press! This solution won't allow sibling assemblies to see each other. . I'll have a solution for that in ~ 2 hours. |
OK! Block-style assembly now supports using collaborators from another assembly's interface, where that concrete version of that assembly is not known until run-time. Here's how: @interface ExtendedMiddleAgesAssembly : TyphoonAssembly
/**
* id<QuestLocator> is actually the middle-ages assembly, but this shows we can extract a protocol, to
* just expose the stuff we want to export.
*/
@property (nonatomic, strong, readwrite) id<QuestLocator> questLocator;
- (id)knightWithExternalQuest;
@end @implementation ExtendedMiddleAgesAssembly
+ (instancetype)assembly
{
ExtendedMiddleAgesAssembly* assembly = [super assembly];
//We're having the proxy stand-in for the interface that won't be bound until run-time.
[assembly setQuestLocator:[TyphoonCollaboratingAssemblyProxy proxy]];
return assembly;
}
- (id)knightWithExternalQuest
{
return [TyphoonDefinition withClass:[Knight class] properties:^(TyphoonDefinition* definition)
{
[definition injectProperty:@selector(quest) withDefinition:[_questLocator environmentDependentQuest]];
}];
}
@end - (void)test_allows_initialization_with_a_collection_of_assemblies
{
TyphoonComponentFactory* factory = [[TyphoonBlockComponentFactory alloc] initWithAssemblies:@[
[MiddleAgesAssembly assembly],
[ExtendedMiddleAgesAssembly assembly]
]];
Knight* knight = [(ExtendedMiddleAgesAssembly*) factory knightWithExternalQuest];
LogDebug(@"Knight: %@", knight);
assertThat(knight, notNilValue());
} Now, here's the thing: Instead of overriding assembly to provide the proxy, I want to have it meta-data driven. But here's the options:
@ratkins, @rhgills , @cesteban, @eriksundin - which of the above options do you like. . . I'm inclinded to option 1 - Typhoon will always treat any property as an external collaborator that will be provided at runtime. |
I'm starting to favor the explicit "annotation" now: Examples: typhoon_provided_at_runtime(questLocator) I would like to finish off this feature in the next day or two. . (Though its already usable in 1.3.7). |
Instead of macro, I'm now just thinking of an abstract call-back method on TyphoonAssembly: - (void)resolveCollaboratingAssemblies
{
[self setQuestProvider:[TyphoonCollaboratingAssemblyProxy proxy]; //Resolved at runtime
[self setCastles:[CastleAssembly assembly] //Hard-coded
} |
Done - used the last option. Pushed as 1.3.8 |
Excellent solution; I think it is much better than the other proposed options. Originally I was partial to option 1 (always proxying) but I like the clarity provided by the single line in -[TyphoonAssembly resolveCollaboratingAssemblies]. |
Typhoon provides a few ways to configure environment dependent components, such as the TyphoonPatcher.
Another common pattern is to group environment dependent components together, so that that a different set is provided for each environment. In the XML-style assembly, you can do this by providing a different file. In the block-style assembly, you can provide a category, however this will only work in logic-style tests.
In application-style tests both the production and test version would be loaded, leading to undefined behavior.
Therefore, support an Assembly made up of many children.
The text was updated successfully, but these errors were encountered: