Objective-C 的上下文和依赖注入
使用上下文和依赖注入以及拦截进行 Objective-C 开发的简单、容易并且非常强大的一种方式。CDI 旨在解决一些常见的软件开发模式,如 依赖注入 / 反转控制、单例 和 拦截(一种最小化的 AOP 方法)。
其主要特性包括
使用 CDI 将减少许多类中的样板代码,提高可读性,并允许更好的测试。拦截功能还将提供按安全、日志和其他方面分离实现代码的能力。
CDI 依赖于其他框架,这意味着您可以使用任何单元测试、模拟或其他框架 (请参阅限制章节)。
以下是一些示例
@interface InjectExample: NSObject
// Let's say you have one class which implements the MyServiceProtocol
...
@property(nonatomic, readwrite) MyServiceProtocol *myService;
...
@end
@implementation InjectExample
...
// Using @inject instead of @synthesize will lookup the
// implementation class at runtime and create the instance automatically
@inject(myService);
...
@end
完整示例代码
@interface InjectExample: NSObject
...
// Let's say you have multiple classes which implements the MyServiceProtocol
@property(nonatomic, readwrite) MyServiceProtocol *myService;
...
@end
@implementation InjectExample
...
// Using @inject with an implementation class which will be
// used to create the myService instance
@inject(myService, MyServiceImplementation);
...
@end
@interface InjectExample: NSObject
...
// Let's say you have a property with a class type
@property(nonatomic, readwrite) NSDate *now;
...
@end
@implementation InjectExample
...
// Using @inject will create a new instance automatically
// containing the current date and time
@inject(now);
...
@end
@interface SingletonExample: NSObject
...
@end
// This annotation will produce a singleton implementation
// for SingletonExample. Inject it into other classes to
// access the unique instance.
@singleton(SingletonExample);
@implementation SingletonExample
...
@end
完整示例代码
// Override the auto-wiring by binding new implementation classes to use mocking objects.
// Your test just needs to use the bindProtocol or bindClass method in the setup of your
// Unit testing framework.
[[CDI sharedInstance] bindProtocol:@protocol(ExampleProtocol) with:[MyMock class]];
// This is a very simple method execution logger.
@interface MethodLoggerInterceptor : CDIInterceptor
@end
@implementation MethodLoggerInterceptor
// The invoke method is called on each method call.
-(void)invoke:(CDIInvocationContext *)context {
NSLog(@"--> Entering [%@:%@]", context.target, context.method);
[context execute];
NSLog(@"<-- Leaving [%@:%@]", context.target, context.method);
}
@end
@interface MyDemo : NSObject {
...
-(void)doDemo;
...
}
@intercept(MyDemo,MethodLoggerInterceptor)
@implementation MyDemo
...
// This method will be surrounded automatically with entering and leaving log messages.
-(void)doDemo {
...
}
...
@end
完整示例代码
要运行示例项目;克隆仓库,然后首先从项目目录运行 pod install
注入元素在初始化方法(init...)之后可用。
CDI 在开发中,可能仍有未知的问题。
已知问题包括
打开
已修复
请在此处报告问题。
在使用开发之前,必须启用CDI。打开 AppDelegate.m
(或任何在应用程序开始时执行的相关类) 并添加以下 initialize
方法到实现中
#import "AppDelegate.h"
#import <CDI.h>
@implementation AppDelegate
...
+(void)initialize {
[super initialize];
// Enable context and dependency injection
[CDI initialize];
}
@end
CDI在MIT许可下可用。有关更多信息,请参阅LICENSE文件。