0

NSManagedObjectサブクラスインスタンスにリソースを注入する方法を試していますが、合理的な方法を見つけることができません。NSManagedObjectサブクラスインスタンスへのリソースの注入

簡単に言えば、エンティティの動作メソッドに必要なサービスを表すオブジェクトがあります。このサービスは、実行時に利用可能にする必要があります。

Plain-Old-Objective-C-Objectでは、このオブジェクトをコンストラクタ引数として渡すか、構築後にプロパティを設定するだけです。デリゲートが必要なオブジェクトの数と同様です。

しかし、awakeFromInsertとawakeFromFetchは明らかにパラメータを取りませんし、NSManagedObjectContextにフックしてNSManagedObjectsのポスト初期化を設定する場所を見つけることもできません。

誰にでも解決策がありますか?完全に不自然な例として

:これは総価格を計算するための最良の方法であるかどうかを無視して

@interface ProductEntity : NSManagedObject 

@property (nonatomic, retain) NSNumber *unitPrice; 
@property (nonatomic, retain) MyTaxCalculatorService *taxCalculatorService; 

- (void)grossPriceForUnits:(NSUInteger)units; 

@end 

@implementation ProductEntity 

@dynamic unitPrice; 
@synthesize taxCalculatorService 

- (void)grossPriceForUnits:(NSUInteger)units 
{ 
    return [self.taxCalculatorService grossAmountForUnitPrice:self.unitPrice quantity:units]; 
} 

@end 

(それは不自然な例だ)、どのように私はProductEntityにtaxCalculatorServiceインスタンスを取得するのでしょうか?私はinitをオーバーライドすることはできませんし、一貫して[entity setTaxCalculatorService:service]を呼び出すことができる場所を見つけることはできません。

思考?

+0

"サービス"クラスの1つの共有インスタンスについて話していますか、各オブジェクトに独自のインスタンスがありますか? – jrturton

+0

すべてのエンティティには、サービスインスタンスへの参照があります。いくつかはそのことを分かち合い、そうでない人もいます。私の考案した例では、いくつかの製品が他の製品とは異なる税計算方法を持っていると想像することができます。 –

答えて

0

これは、次のように呼び出すことはできませんか?

myProductEntityInstance.taxCalculatorService = [[MyTaxCalculatorService alloc] init]; 

これはretainを持つプロパティとして定義されているため、管理対象オブジェクトはそのオブジェクトへの参照を保持する必要があります。エンティティがあるコンテキストでセーブを呼び出すまで、管理対象オブジェクトに対する変更は永続化されないことに注意してください。

+0

問題はそれを呼び出す_where_です。エンティティは、エンティティで定義された任意の関係に従うことによって、任意の「NSFetchRequest」ORによって存在させることができる。理論的には、返されたすべてのエンティティのグラフを歩き、ProductEntitiesを見つけてそのプロパティを設定するコードで、アプリケーションの 'executeFetchRequest'へのすべての呼び出しに従うことができます。それは恐ろしいことだ。 –

+0

ああ、楽しいことに、それらの 'executeFetchRequests'のいくつかは' NSFetchedResultsController'のようなフレームワークコードの中に隠れてしまい、そのような場合にプロパティを設定することさえできません。 –

1

awakeFromFetch/awakeFromInsertが常に呼び出されます。あなたはそれを他の方向からアプローチする必要があります - マネージオブジェクトは他のクラスから "サービス"インスタンスを要求する必要があります(これはクラスメソッドと思われます) - あなたのawakeFrom *メソッドのようなもの:

self.serviceProvider = [ServiceProvider getServiceProviderForObject:self]; 

ServiceProviderクラスは、管理対象オブジェクトに関するすべての情報を持ち、適切なインスタンスを返すことができます。

+0

これは、私が使用している回避策と非常によく似ています - NSManagedObjectContext-> NSManagedObjectサブクラス型名 - >キー+値の3つのレベルの辞書を保持するシングルトンヘルパーは、インスタンスに設定するプロパティのペアです。あなたが言ったように、NSManagedObjectのサブクラスawakeFrom(Insert | Fetch)は、シングルトンに最終的な初期化を依頼します。これはすべて複雑ですが、私はもっと簡単なものがあることを望んでいました。 –

0

私の見解では、これを行う最もクリーンな方法は、grossAmountForUnitPrice:quantity:をTaxCalculatorServiceクラスのClassメソッドに変えることです。

taxCalculatorServiceクラスのインスタンスをインスタンス化する必要なく、[TaxCalculatorService grossAmountForUnitPrice:self.unitPrice quantity:units]を呼び出すことができます。

これは、TaxCalculatorServiceが、特定のロケールなどの税率など、返される値に影響を与える状態でインスタンス化されていないことを前提としています。そうであれば、記述しているようにインスタンスをインスタンス化するために、ここにその情報が必要なので、その追加情報が必要な場合は、代わりにクラスメソッドの追加パラメータとして渡すことができます。