Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Small dependency injection framework for Objective-C
Objective-C Ruby
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
Externals
TBCacao.xcodeproj
TBCacao.xcworkspace
TBCacao
TBCacaoIOS.xcodeproj
TBCacaoIOS
TBCacaoTests add iOS project
.gitignore
LICENSE
Podfile
README.md

README.md

TheobromaCacao — TBCacao

About

TBCacao is a small and simple Cocoa framework for dependency injection.

CocoaPods

  • OS X: pod 'TBCacao'
  • iOS: pod 'TBCacaoIOS'

Example Project

My other project Qmind — a mind mapping app for OS X compatible with FreeMind — uses TBCacao quite extensively. Have a look for a real life example.

Usage

First, include TBCacao in your project by either adding it as a Framework or copying all TBCacao classes into your project. To initialize TBCacao you add the following line to main.m before you return:

[[TBContext sharedContext] initContext];

TBBean

Assume that we have the following two classes:

  • MyLayoutManager
  • MyDrawingManager

Assume further that you want to have MyLayoutManager automatically injected—autowired in the language of Spring—in MyDrawingManager. The two classes look as follows

MyLayoutManager

@interface MyLayoutManager : NSObject <TBBean>

- (void)doLayout;

@end

@implementation MyLayoutManager

- (void)doLayout {
  NSLog(@"doLayout");
}

@end

MyDrawManager

@interface MyDrawManager : NSObject <TBBean>

@property (weak) MyLayoutManager *layoutManager;

- (void)doDraw;

@end

@implementation MyDrawManager

TB_AUTOWIRE(layoutManager)

- (void)doDraw {
    [self.layoutManager doLayout];
}

@end

The protocol TBBean marks both classes as beans such that they are scanned by TBCacao. The line TB_AUTOWIRE(layoutManager) lets TBCacao automatically set the property layoutManager with an instance of MyLayoutManager.

TBManualBeanProvider

Oftentimes you use singltons of Foundation, AppKit/UIKit or other 3rd party frameworks in your classes. For many purposes it is beneficial to have them injected, ie not call messages like [SomeManager sharedManager]. This can easily limit the unit-testability of your classes. Let's assume that you have MyManager and this class uses [NSNotificationCenter defaultCenter]. To inject the default notification center, you do the following

MyManualBeanProvider

@interface MyManualBeanProvider : NSObject <TBManualBeanProvider>
@end

@implementation MyManualBeanProvider

+ (NSArray *)beanContainers {
    static NSArray *manualBeans;

    if (manualBeans == nil) {
        manualBeans = @[
                [TBBeanContainer beanContainerWithBean:[NSNotificationCenter defaultCenter]],
                [TBBeanContainer beanContainerWithBean:[SomeOtherManager sharedManager]],
        ];
    }

    return manualBeans;
}

@end

MyManager

@interface MyManager: NSObject <TBBean>

@property (weak) NSNotificationCenter *notificationCenter;

@end

@implementation MyManager

TB_AUTOWIRE(notificationCenter)

@end

Now, you can easily mock the notification center in your unit test for MyManager.

Since TBCacao automatically scans all classes implementing the protocol TBManualBeanProvider, you don't need an interface file; put both @interface and @implementation in MyManualBeanProvider.m.


TODO: Describe TB_MANUALWIRE.

Something went wrong with that request. Please try again.