Skip to content

What can be Injected

jasperblues edited this page Dec 25, 2014 · 67 revisions

##A definition can be injected with . . .

#Other Definitions

The most common scenario is of course that a definition wishes to be injected with the built instance of another definition.

By Type

For properties, the Objective-C run-time provides type-introspection. Therefore, injection can be done by matching the required-type, as follows:

- (Knight *)knight
{
    return [TyphoonDefinition withClass:[Knight class] configuration:^(TyphoonDefinition *definition) {
        [definition injectProperty:@selector(quest)];
    }];
} 

NB: When injecting by type, Typhoon searches within the bounds of the TyphoonComponentFactory, so it can match components declared in [other assemblies](Modularizing Assemblies)

. . Typhoon will find the component that matches the required type.

see also: Autowiring (Objective-C)

By Reference

Injection can be done by reference. This is useful in the common requirement you have multiple components matching the same class or protocol. The injection is done by referencing a method in the assembly, meaning you can use all of your IDE refactoring tools, as you normally would.

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

- (id<Quest>)quest
{
    return [TyphoonDefinition withClass:[SaveTheKingdomQuestImpl class]];
}

see also: Modularizing Assemblies


#Injecting Typhoon Itself

Typhoon can inject itself. This is useful in order to proceed from one object-graph to another, for example, loading a new view controller to proceed to from the existing one.

  • When injecting Typhoon itself, the property or method parameter can be of type TyphoonComponentFactory
  • When injecting Typhoon itself the property can be any one of your TyphoonAssembly sub-classes (or perhaps even a protocol that represents these).

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

The assembly can be injected either by type, as shown above, or explicitly:

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

Injecting a collaborating assembly: (see Modules)

[definition injectProperty:@selector(assembly) with:self.networkComponents];

. . similarly, the assembly can be injected into initializers, properties or methods.


As an alternative, if you're not worried about your class having a direct dependency on Typhoon, you can also do the following:

#import Typhoon.h

- (void)typhoonSetFactory:(id)theFactory
{
    //_factory is of type TyphoonComponentFactory, but can be cast to any of your 
    //TyphoonAssembly sub-classes, if desired. 
    _factory = theFactory;
}


#Injecting Configuration

Besides injecting other Typhoon-built components, Typhoon can perform configuration by injecting simple objects and primitive values.

###Injecting a Simple Object

[definition injectProperty:@selector(serviceUrl) with:
    [NSURL URLWithString:@"http://www.myapp.com/service"]]; 

###Using Auto-boxing / NSValue to inject primitives

Primitives can be injected using auto-boxing. C-style strings and structs can be injected as an NSValue, Typhoon will unpack the value onto the object instance.

[initializer injectParameterWith:@(NSPrivateQueueConcurrencyType)]; 
[initializer injectParameterWith:@(INT_MAX)];
[initializer injectParameterWith:@YES];
[initializer injectParameterWith:[SomeClass class]];
[initializer injectParameterWith:NSValueFromPrimitive(@selector(selectorValue))];
const char *cString = "Hello Typhoon";
[initializer injectParameterWith:NSValueFromPrimitive(cString)];
[initializer injectParameterWith:[NSValue valueWithRange:NSMakeRange(10, 20)]];
[initializer injectParameterWith:[NSValue valueWithPointer:primitiveStruct]];

More examples of injecting primitives with NSValue: wrap-primitive-values-into-NSValue

##Typhoon Config

If you wish, configuration information can also be extracted into a properties file that can be stored locally or resolved dynamically.

####Create a properties file with the values, as follows:

#for primitive values just write the property value
damsels.rescued=12
hasHorseWillTravel=no

#for object instances, declare the required type:
service.url=NSURL(http://my.backend.net/service-gateway)

####Attach your properties as follows:

to attach a properties file at run-time:

TyphoonConfigPostProcessor* configurer = [[TyphoonConfigPostProcessor alloc] init];
[configurer useResourceWithName:@"Configuration.properties"]];
[factory attachPostProcessor:configurer];

. . to attach a properties file at build-time

- (id)configurer
{
    return [TyphoonDefinition configDefinitionWithName:@"Configuration.properties"];}

. . And now reference a value as follows:

[definition injectProperty:@selector(serviceUrl) with:
    TyphoonConfig(@"service.url")

####Supported formats for properties

Besides the .properties style of config shown above, the following formats are supported.

Plist (ie native Cocoa):

<plist version="1.0">
    <dict>
        <key>hasHorse</key>
        <true/>
        <key>damsels</key>
        <integer>28</integer>
    </dict>
</plist>

Json:

{
    "config": {
        "damsels_rescued": 42,
        "hasHorseWillTravel": true
    }
}

###Registering Type Converters

In the properties file above, we declare the required type and define will convert our value for us. Typhoon contains pre-built type converters, or you can register your own, as follows:

Create a class that conforms to the following:

@protocol TyphoonTypeConverter <NSObject>

- (id)supportedType;

- (id)convert:(NSString*)stringValue;

@end

. . . And then register it with the container as follows:

- (id)myTypeConverter
{
    //Will participate as a type converter as it conforms to the required protocol. 
    return [TyphoonDefinition withClass:[YourConverterClass class]];
}



Quick Start!

Get started in two minutes.

Main Track

Get familiar with Typhoon.

Advanced Topics

Become a Typhoon expert.

Under the Hood

For contributors or the just plain curious.

Clone this wiki locally