Providerとは
Providerという考え方
対象とするオブジェクトを直接注入するのではなく、そのオブジェクトを取得する機能をもったオブジェクトを注入します。コードを見た方が理解しやすいので、下記にCoreData用のプロトコルを引用します。
protocol
#import <Foundation/Foundation.h>
@protocol BTKCoreData <NSObject>
@property(strong,readonly,nonatomic) NSManagedObjectModel *managedObjectModel;
@property(strong,readonly,nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property(strong,readonly,nonatomic) NSManagedObjectContext *managedObjectContext;
@end
@protocol BTKCoreDataProvider <NSObject>
- (id<BTKCoreData>) get;
@end
BTKCoreDataProviderの依存関係を注入しておくと、必要なタイミングでBTKCoreDataを取得することが出来ます。
Providerを用いるメリット
依存関係のタイミングを遅らせることができるため、下記のようなメリットがあります。
- 循環参照の回避
- initializerで依存関係を注入する場合、Providerを用いないと相互参照はすべて循環参照となります。Providerを用いると、相互参照をintializer内で双方から使用しない限り循環参照となりません。
- オブジェクト生成タイミング遅延
- 必要になるまでオブジェクト生成を遅延することができます。オブジェクトの生成コストが高い場合に有効です。
- オブジェクト注入コストの低減
- Providerはロックなしで注入できるので、大量にsingletonを注入する場合などにはちょっと効果があるかもしれません。
Typhoon FrameworkにおけるProvider
残念ながらTyphoon FrameworkとしてのProviderの書き方はありません。
ただ、Provider用のクラスにTyphoonComponentFactoryを注入するだけで簡単に実現できるので、あまり困ることはないと思います。
interface
@interface BTKCoreDataProviderImpl : NSObject<BTKCoreDataProvider>
@property(strong,readonly,nonatomic) TyphoonComponentFactory* factory;
- (id)initWithFactory : (TyphoonComponentFactory*) factory;
@end
implementation
@implementation BTKCoreDataProviderImpl
- (id)initWithFactory : (TyphoonComponentFactory*) factory;
{
self = [super init];
if(!self){
return nil;
}
_factory = factory;
return self;
}
- (id<BTKCoreData>)get
{
return [self.factory componentForType:@protocol(BTKCoreData)];
}
@end
assembly
- (id) coreDataProvider
{
return [TyphoonDefinition withClass:[BTKCoreDataProviderImpl class]
initialization:^(TyphoonInitializer *initializer)
{
initializer.selector = @selector(initWithFactory:);
[initializer injectWithComponentFactory];
}];
}