2017-12-01 8 views
1

私は、ユーザーの電子メールアドレスを取得するためにClaimsPrincipalを知る必要があるNancyモジュールとデコレータクラスを用意しています。だから私は、私が把握するのに苦労しています何NancyにClaimsPrincipalを挿入する方法

public EmailDecorator(IDbConnectionFactory connectionFactory, 
         IPrincipal principal, 
         IEmailClient emailClient) : base(connectionFactory) 

としてコンストラクタを宣言したコンストラクタに元本を注入する方法です。 DI用Simple Injectorを使用しており、非常に効果的です。私はNancyContextのパラメータとして持ってConfigureRequestContainer()方法、私は例外

protected override void ConfigureRequestContainer(
    TinyIoCContainer container, NancyContext context) 
{ 
    container.Register<IPrincipal>((c, o) => context.CurrentUser); 
    base.ConfigureRequestContainer(container, context); 
} 

を取得IPrincipalをインスタンス化するをオーバーライドした場合でも、例外はシンプルインジェクタがデフォルトTinyIOCコンテナに登録されている程度IPrincipalを知らないことを示し。

設定が無効です。 InvoiceModuleタイプのインスタンスの作成に失敗しました。 EmailDecorator型のコンストラクターには、名前が 'principal'で、タイプがIPrincipalで、登録されていないパラメーターが含まれています。 IPrincipalが登録されていることを確認するか、EmailDecoratorのコンストラクタを変更してください。

編集

私はこれを解決しようとするとあまりにも長く費やしてきたと私は答えは、このようにそれをやろうとして停止することであると思います。私の元の例では、間違っているデコレータコンストラクタにIPrincipalを注入しようとしています。代わりに、デコレータのメソッドの1つが呼び出されたときにIPrincipalを導出できるようなサービスを注入する必要があります。 Func<IPrincipal>。リクエストコンテナがTinyIoCContainerであると私はSimpleInjectorを使用していることを除いて

protected override void ConfigureRequestContainer(TinyIoCContainer container, NancyContext context) 
{ 
    container.Register<Func<IPrincipal>>((c, o) => 
    { 
     return() => context.CurrentUser; 
    }); 
} 

:ナンシーは、要求ごとに呼び出され、その潜在的に使用することができオーバーライド可能なメソッドConfigureRequestContainer()を提供します。では、要求コンテナに解像度をオフロードするSimpleInjector登録を追加できますか?

_container.RegisterSingleton<Func<IPrincipal>>(() => nancy.Resolve<Func<IPrincipal>>()); 

実際には、はリクエストコンテナと同じコンテナではありません。だからどこかにIPrincipalを首尾よく解決できるコンテナがありますが、アクセスする方法がわかりません。この演習の目的は、Thread.CurrentPrincipalを呼び出すことができた昔のような、ClaimsPrincipalを含むようにレポコードのメソッドシグネチャを変更する必要がないようにすることでした。依然として手がかりを探していますが、ClaimsPrincipalを含めるようにメソッドのシグネチャを変更し始めます。

+0

あなたの質問にすぐに答えるナンシーの経験はあまりありませんが、ローカルで実行できるGithubの最小の実例にリンクすることができれば、私はこれを理解することができます。 – Steven

+0

シンプルインジェクターのことは分かりませんが、あなたのコードはTiny IoCをリクエストコンテナとして使用しています。おそらく、プリンシパルを間違ったコンテナに登録しようとしています。 ClaimsPrincipalがあなたが登録できるように早期に解決されているかどうかもわかりません。このディスカッションは、ナンシー1.x(プリンシパルの代わりにIUserIdentity)に基づいていますが、関連性がある必要があります。https://github.com/NancyFx/Nancy/issues/1453 – mbnx

+0

はい自分自身がサークルに入っていることがわかりました。 'ConfigureRequestContainer'のNancyContextには' ClaimsPrincipal'が含まれていますが、SImple Injectorからリクエストコンテナにアクセスできません。 –

答えて

0

答えはIHttpContextAccessorです。スタートアップで。

public void ConfigureServices(IServiceCollection services) 
{   
    services.AddSingleton<IAppSettings>(settings); 
    services.AddSingleton<IHttpContextAccessor>(new HttpContextAccessor()); 
    … 
} 

次にブートストラップにパラメータとしてapp.ApplicationServicesを渡します:ブートストラップクラスApplicationStartup()方法で

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IAppSettings settings) 
{ 
    var log = ConfigureLogger(settings); 
    app.UseOwin(buildFunc => 
    { 
     buildFunc.UseMonitoringAndLogging(log, HealthCheckAsync); 
     buildFunc.UseNancy(cfg => 
      cfg.Bootstrapper = new Bootstrapper(env, log, app.ApplicationServices)); 
    }); 
} 

を、シンプルなインジェクターコンテナにサービスを登録CSはConfigureServices()方法で新しいサービス定義を追加します:

デコレータクラスでは、コンストラクタにIHttpContextAccessorを追加します。

public EmailDecorator(IDbConnectionFactory connectionFactory, 
         ILogger log, 
         IHttpContextAccessor httpContextAccessor, 
         IEmailClient emailClient) : base(connectionFactory, log) 
{ 
    _emailClient = emailClient; 
    _httpContextAccessor = httpContextAccessor; 
} 

ClaimsPrincipalは_httpContextAccessor.HttpContextプロパティからアクセスすることができます。

関連する問題