First step is easy


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    self.container = [[[MVIOCContainer alloc] init] autorelease];
    
    //add application delegate into container
    [self.container addComponent:self];
    
    //add application window into container
    [self.container addComponent:self.window];
    
    //Add main controller into container
    [self.container addComponent:[MainController class]];
    
    //Get main controller instance from container
    UIViewController *mainController = 
    	(UIViewController *)[self.container getComponent:[MainController class]];
    
    //place main controller view into window
    [self.window addSubview:mainController.view];
    [self.window makeKeyAndVisible];
    
    return YES;
}

Adding components into container

There is many ways how to add components into container :

Getting components from container

Components should be returned from container on entry points. For example in the application:didFinishLaunchingWithOptions: selector of application delegate can be used something like this:

UIViewController *mainController = 
	(UIViewController *)[self.container getComponent:[MainController class]];
[self.window addSubview:mainController.view];
All other components should be created throught injection as colaborators. Ideal situation is just one usage of getComponent method of container.

Writing classes which can be placed into container

Great emphasis is placed on creating classes as usual. Do not to force users of this framework to inherit some special abstract class or implement protocol. So, how to make it:

//SomeController.h

@interface SomeController : UIViewController {
	//autowire injection
    SomeAppDelegate *injAppDelegate;
    SomeService *service;
}
//make it public and to allow injection
@property(nonatomic, assign) SomeAppDelegate *appDelegate;
@property(nonatomic, retain) SomeService *service;
@property(nonatomic, retain) NextController *nextController;

@end

//SomeController.m

@implementation MainController

//inj prefix tell to container to use autowiring. So he lookup for 'SomeAppDelegate' component and inject it.
@synthesize appDelegate = injAppDelegate;
@synthesize service;
//when we use dynamic we are saying to container that we want lazy load. So collaborator is created in time when we want to use it.
@dynamic nextController;

@end

What we have seen here:

Customization of Container

Injection types

As default container uses property injection type when adding component. But there can be more injection types. It is possible to say which type to use when adding component or it can be setted as default for all addings.

Container now supports two injection types.

It is possible to write your own injection type. Just implement protocol and use it

Caching of components

Caching of components is mainly used to simulate singleton behavior of components. As with injection types, there can be more caching strategies. Framework now support just really easy caching which is in most cases good enough, but it is not thread safe. But other can be written, for example thread safe caching, or caching just in threads ...
How to use cache:

Act on components

Act on component is feature, when you can say 'make some act on created component'. Library currenty implement [[Controller Actor]] which should help with controller views and subviews. It is usable, when you need to do something with instance which is just created. How to use :

Make note, that actor is used just when creating new component. So when you use caching, actor is run upon instance just one time.