Closed jflute closed 2 years ago
f1c4690 の修正は、 behaviorSelector を Named("behaviorSelector") として取得する、ということですよね? これだと、複数DBが3つ目になると同じように破綻してしまうと思います。
Named({DB名}) で取得出来るようにするのが良いと思います。
利用するクラスのコンストラクタが下記のようになるのがいいんじゃないでしょうか。
@Inject
public Foo(BehaviorSelector behaviorSelectorForMainDB,
Named("subDB") BehaviorSelector behaviorSelectorForSubDB,
Named("subDB2") BehaviorSelector behaviorSelectorForSubDB2) {
...
}
複数DBが3つ目になると同じように破綻してしまうと思います。
これは誤りでした。DBごとの名前がついていました。
しかし、Namedにクラス名までつけるのは冗長ですので、 prefixだけNamedに与える方が良いと思うのです。
@XenonAbe ありがとうございます。 このコンポーネント名ですが、projectPrefix もしくは allcommonPrefix と連動するようになっています。
// 複数DB - クラス名の prefix を (必要であれば) 設定する https://dbflute.seasar.org/ja/manual/function/genbafit/projectfit/multipledb/index.html#prefixunique
なるほど、ここはGoogle Guiceと他のDIコンテナとのコンポーネント名に対する扱いの違いでしょうかね。
Spring, Lasta Diだと、コンポーネント名だけでコンポーネントが取得ができます。 (場合によってはフィールドの変数名とかをコンポーネント名と一致させてDIすることも)
BehaviorSelector selector = context.getBean("behaviorSelector"); // spring
ゆえに、コンポーネント名にクラス名っぽいものを入れてコンポーネント全体でユニークに識別しないとなのですが...
Guiceだと、名前だけで取得するような機能はなく、あくまで同じ型の識別情報になるので...
injector.getInstance("behaviorSelector"); // String引数のメソッドはない
同じ型でユニークでありさえすれば良いというところでしょうか?
確かに全部同じ名前で登録してもエラーにはならないんですね。
bind(BehaviorSelector.class).annotatedWith(Names.named("resola")).toInstance(behaviorSelector);
bind(BehaviorCommandInvoker.class).annotatedWith(Names.named("resola")).toInstance(behaviorCommandInvoker);
bind(InvokerAssistant.class).annotatedWith(Names.named("resola")).toInstance(invokerAssistant);
bind(CommonColumnAutoSetupper.class).annotatedWith(Names.named("resola")).toInstance(commonColumnAutoSetupper);
ただ、injector.getInstance(Key key); という Key で取得するメソッドが気になっています。 でもこれも、型を指定すること前提ですかね。ちょっと調べてみます。
@XenonAbe injector.getInstance(Key key)も基本的には型をベースに名前を補足的に使う感じのようですね。
DBFluteの中でコンポーネント名がDIコンテナ間でルールが変わってしまうので、何かそこに依存するロジックがあったら?ってのが若干不安ですが... 恐らくないはずですし、あってもGuiceに閉じる話なので気軽に対応できると思うので、アプリ側で利用しやすい形に直したいと思います。
ただ、isDBFluteModuleGuiceRuntimeComponentByName=trueのときで、 projectPrefixやallcommonPrefixが設定されていないときはエラーになるようにしました。 isDBFluteModuleGuiceRuntimeComponentByNameはprefixがあること前提となります。
jflute memo: prefixが設定されてないのにbyNameのときのエラーハンドリングを実装。
ただ、isDBFluteModuleGuiceRuntimeComponentByName=trueのときで、 projectPrefixやallcommonPrefixが設定されていないときはエラーになるようにしました。
こんな感じのエラーを出すようにした。
[df-generate] ... 34 more
[df-generate] Caused by: org.dbflute.exception.DfIllegalPropertySettingException: Look! Read the message below.
[df-generate] /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
[df-generate] Guice byName requires projectPrefix or allcommonPrefix.
[df-generate]
[df-generate] [Advice]
[df-generate] If isDBFluteModuleGuiceRuntimeComponentByName=true,
[df-generate] then use projectPrefix or allcommonPrefix.
[df-generate]
[df-generate] isDBFluteModuleGuiceRuntimeComponentByName is on dependencyInjectionMap.dfprop.
[df-generate] projectPrefix, allcommonPrefix are on basicInfoMap.dfprop.
[df-generate]
[df-generate] [componentName (for debug)]
[df-generate] behaviorSelector
[df-generate] * * * * * * * * * */
@XenonAbe prefixのみがnamedに入るようにしました。
bind(BehaviorSelector.class).annotatedWith(Names.named("resola")).toInstance(behaviorSelector);
bind(BehaviorCommandInvoker.class).annotatedWith(Names.named("resola")).toInstance(behaviorCommandInvoker);
bind(InvokerAssistant.class).annotatedWith(Names.named("resola")).toInstance(invokerAssistant);
bind(CommonColumnAutoSetupper.class).annotatedWith(Names.named("resola")).toInstance(commonColumnAutoSetupper);
active-hangarプロジェクトで試しています。 https://github.com/dbflute-test/dbflute-test-active-hangar
ドキュメントにも反映しました https://dbflute.seasar.org/ja/manual/function/genbafit/projectfit/multipledb/index.html#runtimebyname
done, released at 1.2.6
Feedback from DBFlute Slack: https://dbflute.slack.com/archives/CAPH91CH2/p1651136409033359