ObjectivePim 是一个基于 Pimple 源代码(包括此文件 :P)的 Objective-C 小型依赖注入容器。
获取 ObjectivePim 的支持方式是使用 CocoaPods。
将 ObjectivePim 添加到您的 Podfile
platform :ios, '6.1'
pod 'ObjectivePim'
创建容器只需实例化 OPContainer
类
#import <ObjectivePim/ObjectivePim.h>
OPContainer *container = OPContainer.new;
像许多其他依赖注入容器一样,ObjectivePim 可以管理两种不同的数据:服务和参数。
定义参数就像使用 ObjectivePim 实例作为字典一样简单
// define some parameters
container[@"foo"] = @"bar";
container[@"default_items"] = @5;
服务是一个作为更大系统一部分执行的特定对象。例如,服务:数据库连接、模板引擎、邮件发送者。几乎任何对象都可以是服务。
服务是通过返回对象实例的代码块定义的
// define some services
container[@"service"] = ^(void) {
return Foo.new;
};
__block OPContainer *container = OPContainer.new;
container[@"other_service"] = ^(void) {
return [[Bar alloc] initWithValue:container[@"value"]];
};
注意在第二个例子中,代码块可以访问当前容器实例,允许引用其他服务或参数。
由于对象仅在获取时才会创建,因此定义的顺序无关紧要,也不会有性能损失。
使用定义的服务也很容易
// get the service object
id service = container[@"service"];
因为 ObjectivePim 将代码块视为服务定义,所以需要用 protect:
方法包装代码块,以便将它们作为参数存储
container[@"random"] = [container protect:^(void){
return @(arc4random());
}];
在某些情况下,您可能希望修改定义后已定义的服务定义。您可以使用 extend:
方法定义随后在被创建的服务上运行的附加代码
container[@"afnetworking"] = ^(void) {
NSURL *baseURL = [NSURL URLWithString:@"http://somehost.com"];
return [[AFAppDotNetAPIClient alloc]
initWithBaseURL:baseURL];
};
[container extend:@"afnetworking" withCode:^(id service, OPContainer *container) {
AFAppDotNetAPIClient *client = (AFAppDotNetAPIClient *)service;
client.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
}];
第一个参数是对象名称,第二个是获取对象实例和容器的块。
如果您反复使用相同的库,您可能希望将一些服务从一个项目重用到另一个项目;通过实现OPServiceProviderProtocol
将您的服务打包到一个提供者中
@interface FooProvider : NSObject<OPServiceProviderProtocol>
@end
@implementation FooProvider
- (NSString *)identifier
{
return @"foo";
}
- (void)registerProvider:(OPContainer *)container
{
// register some services and parameters
// on container
}
@end
然后,提供者可以轻松地在容器上注册
[container register:FooProvider.new];
FooProvider *foo = container[@"foo"];
默认情况下,每次您获取服务时,ObjectivePim都会返回相同的实例。如果您希望对于所有调用都返回不同的实例,请使用factory:
方法包装您的block
container[@"service"] = [container factory:^(OPContainer *container) {
return [[Foo alloc] initWithValue:container[@"key_to_value"]];
}];