Typhoon Inject Property to a new object

325 Views Asked by At

I am start to use DI containers on iOS and I don't have idea how to inject property in this case:

Imagine we have:

Assembly.m

- (ClassA *)classA {
    return [TyphoonDefinition withClass:[ClassA class] configuration:^(TyphoonDefinition *definition) {
        [definition injectProperty:@selector(url) with:@"http://inject:URL"];
    }];
}

And two classes

ClassA

@interface ClassA : NSObject
@property (nonatomic,readwrite) NSString *url;
@end

ClassB

@interface ClassB : ClassA
@end

And

ViewController.m

@interface ViewController ()
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];

   ClassB *cB = [ClassB new]; 
    NSLog(@"%@",cB.url);
}

I want to where I create new object by ClassB, all objects has injection with url property from my DI container (assembly) Yes I can add property to my ViewController and this injection works fine, but I need inject property to new object.

Maybe I don't understand all principles but I should ask. Thx

1

There are 1 best solutions below

4
Nikita Ermolenko On BEST ANSWER

Try this.

- (id)classAObject{
    return [TyphoonDefinition withClass:[ClassA class]
                          configuration:^(TyphoonDefinition *definition){
                              [definition injectProperty:@selector(url) with:@"http://inject:URL"];
                          }];
}

- (id)classBObject{
    return [TyphoonDefinition withParent:[self classAObject] class:[ClassB class]];
}

KSTTestAssembly *assembly = [[KSTTestAssembly alloc] init];
[assembly activate];

id classB = [assembly classBObject];

Bootstrapping Typhoon

You can bootstrap Typhoon, and hold a reference to it, Typically in the AppDelegate. In other parts of the application, we don't want to obtain an instance of Typhoon directly:

  • We're coupling our application directly to Typhoon
  • This is not dependency injection, difficult to test, etc

So what we do instead is:

  • Inject the assembly (or one of the assemblies, in a modular set-up) into the class where we need it. Once an assembly is activated, this will actually be an instance of TyphoonComponentFactory posing as an assembly.

  • It will serve as a factory for emitting a built object graph.

  • Typhoon's default scope is ObjectGraph. So, we don't hold any objects in memory - just recipes for building them. The object graph is instantiated just when we need it.
  • In this way we can proceed from one object graph to another efficiently, and in a loosely coupled way.

Example:

- (RootViewController *)rootController
{
    return [TyphoonDefinition withClass:[RootViewController class] 
    configuration:^(TyphoonDefinition* definition) {
        [definition injectProperty:@selector(assembly)];
    }];
}

The documentation for this feature is here.

Storyboards:

If you like to use story boards and Objective-C, you can use auto-injection macros on your view controllers.