Skip to content

Backing a TyphoonAssembly with a factory protocol

Hok Shun Poon edited this page Sep 17, 2015 · 2 revisions

It's possible to define a protocol to back your assemblies, for all or some assembly methods, with or without runtime arguments. For example, instead of the following:

// FriendListViewController.h
@interface FriendListViewController

@property (nonatomic, strong, readonly) MyAssembly* assembly;

@end

// MyAssembly.h
@interface MyAssembly: TyphoonAssembly
- (id)userDetailsControllerForUser:(User *)user;
@end

We can extract MyAssembly's interface into a protocol and define this instead:

// UserDetailsControllerAssemblyProtocol.h
@protcol UserDetailsControllerAssemblyProtocol
- (id)userDetailsControllerForUser:(User *)user;
@end

// FriendListViewController.h
@interface FriendListViewController
@property (nonatomic, strong, readonly) id<UserDetailsControllerAssemblyProtocol> assembly;
@end

... then we make MyAssembly conform to this assembly protocol. It can then be injected into FriendListViewController as follows:

@interface MyAssembly : TyphoonAssembly <UserDetailsControllerAssemblyProtocol>
// No declarations here necessary
@end

@implementation MyAssembly

- (id)friendListController
{
 return [TyphoonDefinition withClass:[FriendListViewController class]
 configuration:^(TyphoonDefinition *definition) {

 [definition injectProperty:@selector(provider) with:self];
 }];
}

- (id)userDetailsControllerForUser:(User *)user
{
    return [TyphoonDefinition withClass:[UserDetailsViewController class]
        configuration:^(TyphoonDefinition *definition) {

        [definition useInitializer:@selector(initWithPhotoService:user)
            parameters:^(TyphoonMethod *initializer) {

            [initializer injectParameterWith:[self photoService];
            [initializer injectParameterWith:user];
        }];
    }];
}

@end

Tip: Backing your factory methods with a protocol means that, if you inject the assembly your classes do not have a direct dependency on Typhoon. This is considered to be good practice, and in the spirit of dependency injection.