none
Prismを使ってIHttpClientFactoryを利用したい RRS feed

  • 質問

  • Prism(.NET Core3.1、DryIoc)を使ったWPFアプリケーションで、メイン画面のViewModelのコンストラクタにIHttpClientFactoryを定義し取得したいが、メイン画面のViewのコンストラクタのInitializeComponent()メソッドで下記のような例外が発生する。

    --------------------------------------

    内部例外 1:
    ContainerResolutionException: An unexpected error occurred while resolving 'SamplePrismDryIocApp.ViewModels.MainWindowViewModel'

    内部例外 2:
    ContainerException: code: Error.UnableToResolveUnknownService;
    message: Unable to resolve Microsoft.Extensions.DependencyInjection.IServiceScopeFactory as parameter "scopeFactory" (IsSingletonOrDependencyOfSingleton)
      in Resolution root Singleton Microsoft.Extensions.Http.DefaultHttpClientFactory {DryIoc.IfUnresolved.ReturnDefaultIfNotRegistered} FactoryId=168 (IsSingletonOrDependencyOfSingleton, IsResolutionCall)
      from container without scope

    --------------------------------------

    APPクラスでは以下のように定義しているが、上記の「IServiceScopeFactory」のコンテナ定義をどのようにしたらよいのか。

    --------------------------------------

        public partial class App : PrismApplication
        {
            protected override Window CreateShell()
            {
                return Container.Resolve<MainWindow>();
            }

            protected override void RegisterTypes(IContainerRegistry containerRegistry)
            {
                containerRegistry.RegisterServices(s => {
                    s.AddHttpClient();
                });
            }
        }

    --------------------------------------

    インストールしているパッケージは以下の通りです。

    ・Microsoft.Extensions.Http(5.0.0)

    ・Microsoft.Extensions.Http,Polly(5.0.1)

    ・Prism.Container.Extensions(8.0.62)

    ・Prism.DryIoc(8.0.0.1909)

    2021年3月9日 11:53

回答

すべての返信

  • Prism とかは触ったこともないので大ハズレかもしれませんが・・・

    Microsoft.Extensions.DependencyInjection はインストールされてますか? ASP.NET Core アプリを Visual Studio のテンプレートを使って生成した場合はプロジェクトに組み込まれるのですが(DI 機能を利用するので)、質問者さんのアプリは?

    インストールされてなければ NuGet からインストールできます。以下の記事の画像を見てください。

    .NET Core での Dependency Injection
    http://surferonwww.info/BlogEngine/post/2021/01/01/dependency-injection-for-dotnet-core-application.aspx

    HttpClient のインスタンスの生成・廃棄を繰り返すことによるソケットの枯渇、それに対処するためシングルトンにして長期に使いまわすと DNS の変更が反映されないという問題に対処するため、Core に備わっている DI 機能を使って IHttpClientFactory オブジェクトを注入する方法でそれらの問題を回避できるということのようです。

    ASP.NET と HttpClient (CORE)
    http://surferonwww.info/BlogEngine/post/2020/11/08/use-of-httpclient-in-aspnet-application.aspx

    ハズレだったらすみません。

    • 回答としてマーク staka.winner 2022年9月1日 0:56
    2021年3月10日 0:43
  • ご指摘ありがとございます。

    Microsoft.Extensions.DependencyInjectionのパッケージもインストールしてみました。

    ですが、同じところで例外を発し、落ちるようです。

    ご記載の通り、ASP.NETの運用のようなConfigureServicesメソッドを利用したようなIHttpClientFactory による運用をPrismでもしたいのですが、なかなかうまくいかないようです。

    色々と情報、有難うございます。


    2021年3月10日 4:00
  • > Microsoft.Extensions.DependencyInjectionのパッケージもインストールしてみました。
    > ですが、同じところで例外を発し、落ちるようです。

    NuGet パッケージをインストールしただけでは DI 機能は実装されないので、ASP.NET Core のようにテンプレートで組み込み済みということでなければ、自力で実装する必要があるのではないですか?

    紹介した一番目の記事に書いたようにコンソールアプリにさえも実装できるので、自力での DI 機能の実装を検討してはいかがですか。
    • 回答としてマーク staka.winner 2022年9月1日 0:56
    2021年3月10日 8:56
  • ご返信ありがとうございます。

    一番目の記事を改めて拝見させて頂きました、DI機能の実装例が提示されていましたね、勉強になります。

    今のところ実装予定はないのですが、現在はPrismのコンテナ拡張機能である下記メソッドを利用して対応仕様しているのですが、

      protected override IContainerExtension CreateContainerExtension()

    同様なエラー状態となってしまい、どうやったらよいものか悩み検討・調査中です。

    様様な参考文献をご提示いただき、またご指摘もいただきありがとうございます。

    2021年3月10日 11:54
  • staka.winnerさん、こんにちは。フォーラムオペレーターのKumoです。
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    Prismはサードパーティの製品なのですが、より良いサポートのため、ここ(英語サイト)にご投稿いただくことをお勧めします。


    お手数ですが、ご協力の程どうかよろしくお願いいたします。


    MSDN/ TechNet Community Support Kumo ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、 ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    • 回答としてマーク staka.winner 2022年9月1日 0:56
    2021年3月11日 5:43
    モデレータ
  • お騒がせして済ません、そーですねサードパーティなのですよね、ついついここに載せてしまいました。

    ご指摘のサイトに問い合わせてみたいと思います。

    ご指摘、有難うございます。

    2021年3月11日 5:57
  • Prism.Container.Extensions は WPF + Prism + DryIoc では動かないです。

    具体的にPrism本家ではなくて、 Prism.Container.Extensions のissues に聞くべきですが、

    既に Xamarin.Forms で動作するが、それ以外では動作しないとの回答があります。

    Please provide a sample WPF application using Prism.Microsoft.DependencyInjection.Extensions · Issue #157 · dansiegel/Prism.Container.Extensions (github.com)

    なので、 Prism.Container.Extensions は使用すべきではありません。

    ただ、 Microsoft.Extensions.DependencyInjection 自体を組み込んで動かす方法が無いわけではなく、Prism のコンテナーのネイティブ実装側に

    Container.RegisterServices(v =>
    {
          v.AddTransient<IA>(v => new A1());
    });

    https://github.com/juner/Prism.Extensions.ServiceCollection/blob/39b0fc0f666a4dd37b8169063ff2ca52b9743b8f/DryIoc.Microsoft.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs#L21-L24

    の様に生やす DryIoc.Microsoft.DependencyInjection.Extension 1.0.0.2 みたいのを使えば動作はしますね。

    (このライブラリは DryIoc側の設定に寄らずに ISerivceCollection を登録する処理を書いているので 大体の場合に動く筈です。

    サンプル:

    juner/20210525_PrismDryIocHttpClientSample: PrismDryIocHttpClientSample (github.com)



    • 編集済み juners 2021年5月25日 9:53
    • 回答としてマーク staka.winner 2022年9月1日 0:56
    2021年5月25日 5:00