Search code examples
objective-ctyphoon

Extent existing objectgraphs with typhoon


Let's say there are several kingdoms. Each kingdom has a castle. Now I want to create some knights for one of this kingdoms.

The interfaces look like this:

@interface Castle : NSObject
@end

@interface Kingdom : NSObject
@property(nonatomic, strong)Castle *castle;
@end

@interface Knight : NSObject
@property(nonatomic, strong)Castle *address;
@end

The actual internal implementation of the knights requires a reference to the castle. Here is my Definition:

-(Knight *)knight
{
    [TyphoonDefinition withClass:[Knight class] configuration:^(TyphoonDefinition *definition) {
        [definition injectProperty:@selector(address) with:[self castle]];
    }];
}

This is obvious wrong. What I want to express is "please create a knight for my kingdom and if you need a castle (or something else in my kingdom), then use the right one".

I could overcome this problem with a castle-runtime-argument. But the fact, that the knight needs this castle is an implementation detail. Maybe future knight implementations need something else.

I can achieve the behavior i want with the following code:

MiddleAgesAssembly* assembly = [[MiddleAgesAssembly assembly] activate];
id<TyphoonComponentsPool> objectGraphSharedInstances = [assembly valueForKeyPath:@"factory._objectGraphSharedInstances"];
    [objectGraphSharedInstances setObject:castle forKey:@selector(castle)];

[assembly knight];

This is not very elegant, but it solves the problem in this example.

A more general approach would be to register a custom TyphoonComponentsPool's in the factory with corresponding scopes for the definitions.

Are there any plans in this direction? Or maybe there is a better way to solve this kind of problems?

Thanks, Felix


Solution

  • Here's how to do it using Typhoon's current feature set:

    • Define a holder object with scope singleton, lazy singleton or weak singleton. This holder object has mutable properties or methods to pass in context objects.
    • Define other definitions that use the holder object as a factory.
    • Inject these into whatever you need.

    As mentioned in comments, we're happy to explore alternative features/enhancements in the GitHub tracker.