2011-07-16 13 views
2

私はstackoverflowとguiceの両方に新しいです。私がやろうとしていることがguiceで可能かどうかはわかりませんが、確かにそうだと思います。カスタム注釈に基づくバインド

私の問題のドメインは、私がドキュメントを読むシステムを書こうとしていることです。 DocumentReaderのインタフェースを定義しました。

public interface DocumentReader { 
    MetaData readDocument() throws Exception 
} 

サポートされているファイルタイプ(拡張子)を定義する列挙も定義しました。

public enum FileType { 
    doc, 
    png, 
    txt, 
} 

各ファイルタイプの実装方法については、そのファイルタイプの解析方法の詳細が記載されています。この時点で、私は成功し&を書かれている

public class MSWordReaderImpl implements DocumentReader { 
    // .... 
} 

public class PlainTextReaderImpl implements DocumentReader { 
    // .... 
} 

は、これらの各オブジェクトを注入するMapBinder & FactoryModuleProviderを使用して、モジュールをテストしました。存在する各DocumentReader実装は個別にMapBinderに追加されます。私が望んでいるのは、DocumentReaderの追加実装が書かれているので、サポートしているFileTypeで注釈を付けるだけで、GUICEはアノテーションを読み込んでMapBinderに適切に追加できるということです。追加ごとにモジュールを更新してください)。私が想定してきたことは、このようなものです:

@SupportedFileTypes(filetypes={ doc, docx }) 
public class MSWordReaderImpl implements DocumentReader { 
    // .... 
} 

@SupportedFileTypes(filetypes={txt}) 
public class PlainTextReaderImpl implements DocumentReader { 
    // .... 
} 

私はGuiceのドキュメントを通じて数回読んだが、(それも可能であれば!)私はこれを実現する方法を見ていませんよ。どんな助けもありがとう。

ありがとうございます!

答えて

1

のようなコードを書くことができますリフレクションを使用してクラスが入るパッケージをスキャンし、DocumentReaderを実装するクラスを探し、@SupportedFileTypesと注釈を付けたクラスを探します。見つかったら、ファイルタイプごとにMapBinderに追加します。

あなたはクラスパスをスキャンしたくない場合は、あなたはまだこのようなメソッドを書くことで、自分自身のためにこれを簡素化することができます:

private void bindDocumentReaders(Class<? extends DocumentReader>... types) { 
    for (Class<? extends DocumentReader> type : types) { 
    FileType[] supportedFileTypes = type.getAnnotation(SupportedFileTypes.class) 
     .filetypes(); 
    // add to MapBinder for each file type 
    } 
} 
+0

これは私が検討してきた解決策です。 GUICEが箱から出したものなのかどうかは分かりませんでした。私がドキュメントで読んだところから、GUICEモジュールは軽量であることを意図しています(例外をスローすることさえできません)。クラスパスのスキャンは軽いとは思えませんが、おそらく私の選択肢は限られています。 – scubadev

+0

@ Zildijan85:Guiceモジュールは、あなたが望むほど軽量であるかどうかは分かりません。多くの場合、シンプルなバインディングと非常に軽量ですが、場合によってはファイルやその他のものを読むことが必要な場合があります。 Guiceはクラスパスのスキャンのためのサポートを提供していません。通常、クラスパスを明示する方が好きです。 – ColinD

+0

私はこのアプローチが私の目的のために働くと信じています。私のモチベーションは、第三者がカスタムリーダーを書くことを可能にするプラグインシステムを作ることです。私は、サードパーティがDocumentReaderを実装し、その実装に@SupportedFileTypes({x、y、z})で注釈を付けるだけでよいようにしたいと思います。私はあなたのソリューションに似たものをDocumentReaderDiscovertyServiceに配置する方向に傾いています。 DocumentReader GUICEモジュールは、このサービスを呼び出してすべての実装を検索します。発見サービスは、第三者が自分の仕事を識別できるように、設定または別の仕組みを使用することができます。 – scubadev

1

この動作の仕組みを確認する最も簡単な方法は、NamedおよびNamesクラスのソースと、それがどのようにusedであるかを調べることです。まずRequiredFileType注釈を作成

@Retention(RUNTIME) 
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD }) 
@BindingAnnotation 
public @interface RequiredFileType { 
    FileType value(); 
} 

は、文書リーダ等に依存クラスに注釈を付ける、

@Inject 
ServiceRequiringWordReader(@RequiredFileType(doc) DocumentReader reader) 

次に名(コードが省略さ)に相当するRequiredFileTypesユーティリティを作成し、あなたのモジュールには、

bind(DocumentReader.class) 
    .annotatedWith(RequiredFileTypes.for(doc)) 
    .to(MSWordReaderImpl.class); 
bind(DocumentReader.class) 
    .annotatedWith(RequiredFileTypes.for(docx)) 
    .to(MSWordReaderImpl.class); 
bind(DocumentReader.class) 
    .annotatedWith(RequiredFileTypes.for(txt)) 
    .to(PlainTextReaderImpl.class); 
+0

私が見て名前付き&名前のユーティリティを見てみる必要があります彼らに宝石があれば。あなたの答えは役に立ちますが、私が探していたものを満足させるかどうかはわかりません。 ServiceRequiringWordReaderでは、コンストラクタ内のサポートされているすべてのファイルタイプについて知る必要があります。 MSWordReaderImplに、サポートするファイルタイプの注釈を付け、FileTypeが関連付けられている唯一の場所であることを希望します。あなたのソリューションでは、新しい実装が作成されるたびにServiceRequiringWordReaderを更新する必要があると思います。 – scubadev

関連する問題