OCInjection 0.0.1

OCInjection 0.0.1

测试已测试
语言语言 Obj-CObjective C
许可证 MIT
发布最后发布2014年12月

Aryan Ghassemi维护。



  • 作者
  • Aryan Ghassemi

Objective-C的依赖注入框架。DI容器会延迟初始化属性,从而提高性能。注入属性如同标记为@dynamic一样简单

此框架仍在开发中,不建议在生产环境中使用。

配置DI容器

为了配置绑定,创建一个新的从'DIAbstractModule'继承的类,并实现'configure'方法

#import "DIAbstractModule.h"

@interface DIConfig : DIAbstractModule

@end
@implementation DIConfig

- (void)configure
{
    [self bindClass:[YahooClient class] toClass:[YahooClient class]];
    [self bindProtocol:@protocol(GoogleClientProtocol) toClass:[GoogleClient class]];
    [self bindProtocol:@protocol(ClientProtocol) toClass:[Client class]];
}

@end
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    DIConfig *config = [[DIConfig alloc] init];
    [[DIInjector sharedInstance] setDefaultModule:config];

    return YES;
}

使用DI

注意,当属性意在注入时,将其标记为@dynamic

@interface ViewController : UIViewController

@property (nonatomic, strong) IBOutlet UIWebView *webView;
@property (nonatomic, strong) YahooClient *yahooClient;
@property (nonatomic, strong) id <GoogleClientProtocol> googleClient;

@end
@implementation ViewController
@synthesize webView;
@dynamic googleClient;
@dynamic yahooClient;

- (IBAction)fetchGoogleDate:(id)sender
{
    NSString *htmlString = [self.googleClient fetchSearchResultForKeyword:searchKeyWord];
    [self.webView loadHTMLString:htmlString baseURL:nil];
}

- (IBAction)fetchYahooData:(id)sender
{
    NSString *htmlString = [self.yahooClient fetchYahooHomePage];
    [self.webView loadHTMLString:htmlString baseURL:nil];
}

@end

为单元测试模拟依赖

@implementation DIMockConfig

- (void)configure
{
    OCMockObject *yahooClientMock = [OCMockObject niceMockForClass:[YahooClient class]];
    OCMockObject *googleClientMock = [OCMockObject mockForProtocol:@protocol(GoogleClientProtocol)];
    OCMockObject *mockClient = [OCMockObject mockForProtocol:@protocol(ClientProtocol)];

    [self bindClass:[YahooClient class] toInstance:yahooClientMock];
    [self bindProtocol:@protocol(GoogleClientProtocol) toInstance:googleClientMock];
    [self bindProtocol:@protocol(ClientProtocol) toInstance:mockClient];
}

@end

示例单元测试

@interface ViewControllerTests : SenTestCase

@property (nonatomic, strong) ViewController *viewController;

@end
@implementation ViewControllerTests
@synthesize viewController;

#pragma mark - Setup & TearDown -

- (void)setUp
{
    [super setUp];

    DIMockConfig *module = [[DIMockConfig alloc] init];
    [[DIInjector sharedInstance] setDefaultModule:module];

    self.viewController = [[ViewController alloc] init];
}

- (void)tearDown
{
    self.viewController =  nil;

    [super tearDown];
}

#pragma mark - Tests -

- (void)testShouldCallCleintWithGoogleUrl
{
    static NSString *expectedSearchTerm = @"DependencyInjection";
    [[(OCMockObject *)self.viewController.googleClient expect] fetchSearchResultForKeyword:expectedSearchTerm];
    [self.viewController fetchGoogleDate:nil];
    [(OCMockObject *)self.viewController.googleClient verify];
}

- (void)testShouldCallCleintWithYahoo
{
    [[(OCMockObject *)self.viewController.yahooClient expect] fetchYahooHomePage];
    [self.viewController fetchYahooData:nil];
    [(OCMockObject *)self.viewController.yahooClient verify];
}

@end

内联依赖解析

// Resolving Protocol
id <GoogleClientProtocol> googleClient = [[DIInjector sharedInstance] resolveForProtocol:@protocol(GoogleClientProtocol)];

// Resolving Class
YahooClient *yahooClient = [[DIInjector sharedInstance] resolveForClass:[YahooClient class]];