1

ServiceStackで作成された Service があります。デフォルトで ServiceStack に付属しているため、依存性注入に Funq を使用していますが、これは他の DI コンテナーで見られる動作である可能性があります。

起動時にタイプを登録します。

this.AppContainer.RegisterAs<ConcreteDownloadServices, IDownloadServices>();`

クラスにこのコンストラクタがあります:

private readonly IDownloadServices downloadServices;

public ExampleService(IDownloadServices downloadServices)
{
    this.downloadServices = downloadServices;
}

そして、私の具体的な実装のコンストラクターは次のとおりです。

public ConcreteDownloadServices()
{
    this.ArbitraryProperty = "ArbitraryString";
}

すべてが正常に解決され、コードにステップインして、期待どおりに動作することを確認できます。ただし、AbritraryProperty正しく設定されません。ステップスルーして、文字列値に設定されていることを確認できますが、コードが呼び出し元のコード (この例では、のコンストラクターExampleService)に戻るとすぐにArbitraryPropertynull になります。

  1. この動作は設計によるものですか?
  2. 設計によるものである場合、DI を使用することは、具体的な実装のコンストラクターで何もするべきではないことを意味しますか?
  3. 仕様によるものである場合、自動プロパティのデフォルト値を設定する正しい方法は何ですか?
  4. 設計によるものではない場合、何が起こっているのでしょうか?
4

2 に答える 2

4

編集:

これは決して望ましくない動作であると判断したため、コミットをチェックインして、Funq が文字列 (および ValueType) プロパティを自動配線しないように強制しました。新しい動作は、ServiceStack の次のバージョン (v3.9.34) で利用できるようになります。

既存の動作

RegisterAs は Autowired API です。

Container.RegisterAs<ConcreteDownloadServices, IDownloadServices>();

これにより、ServiceStack の IOC は、IOC によって解決された依存関係をすべてのパブリック プロパティに入力するように指示されます。これはstringパブリック プロパティであるためstring、IOC から登録されたものを解決しようとします。コード用語では、これはボンネットの下で行われています。

new ConcreteDownloadServices { 
    ArbitraryProperty = Container.TryResolve<string>()
};

「文字列」が登録されていないため、プロパティを でオーバーライドしますnull。パブリック プロパティのみが自動配線されるため、保護されたプライベート プロパティまたは内部プロパティに変更することで、この動作を回避できます。

それ以外の場合は、依存関係の構築を完全に制御できるカスタム デリゲート ファクトリを登録することで、デフォルトの IOC 動作をオーバーライドできます。

container.Register<IDownloadServices>(c => new ConcreteDownloadServices());
于 2013-01-24T18:21:36.117 に答える
1

開発チームの一部のメンバーは、同様の問題のデバッグに時間を費やしました。

単体テストの 1 つで使用されている RegisterAs クラスには、パブリック メンバーがあります。設定; }

このクラスが Funq によって解決されると、コンストラクターで設定されていても、メンバーは null に設定されます。

私たちのチームメンバーは、メンバーが Container.RegisterAs<> として登録されている型ではない場合に、Funq によってこのメンバーが null に設定されるのは奇妙であることに同意します。

ServiceStack バージョン 4.0.33 を使用しています

于 2015-02-24T14:47:12.377 に答える