2016-04-04 23 views
5

私はカスタムDbContextを実装するクラスライブラリを開発しようとしています。 DbContextSaveChangesメソッドでは、監査目的で現在のユーザーの情報(部門、ユーザー名など)を取得する必要があります。 DbContextコードの一部は以下の通りです:Netコアを使用してDbContextでユーザー情報を取得する方法

public override int SaveChanges() 
{ 
    // find all changed entities which is ICreateAuditedEntity 
    var addedAuditedEntities = ChangeTracker.Entries<ICreateAuditedEntity>() 
      .Where(p => p.State == EntityState.Added) 
      .Select(p => p.Entity); 

    var now = DateTime.Now; 

    foreach (var added in addedAuditedEntities) 
    { 
     added.CreatedAt = now; 
     added.CreatedBy = ?; 
     added.CreatedByDepartment = ? 
    } 
    return base.SaveChanges(); 
} 

心に来る二つのオプション:

  • IHttpContextAccessorを注入し、DbContextは異なり、この場合、( HttpContext.Itemsから情報を取得し、ユーザー情報を保持するためにHttpContext.Itemsを使用しましたHttpContext、それは ですか?
  • HttpContext.Itemsの代わりにThreadStaticオブジェクトを使用し、objeから情報を取得していますか? CT(私はThreadStaticが安全ではないこと、いくつかの記事に を読む)

質問:私の場合に最も適しているのですか?あなたが提案する別の方法がありますか?

+1

あなたのDbContextでIHttpContextAccessorに直接依存するのではなく、AuditLoggerのようなサービスクラスを作成してDbContextに依存させないようにしてください。AuditLoggerはIHttpContextAccessorを独自の内部実装の詳細 –

+0

に依存することができます。それを実装しようとする。ありがとう。 –

答えて

12

this blog postに記載されているようなアプローチを実装しましたが、基本的に依存関係注入を使用して特定のコンテキストにHttpContext(および基礎をなすユーザー情報)を注入するサービスを作成します。 。

非常に基本的な実装は次のようになります。

public class UserResolverService 
{ 
    private readonly IHttpContextAccessor _context; 
    public UserResolverService(IHttpContextAccessor context) 
    { 
     _context = context; 
    } 

    public string GetUser() 
    { 
     return await _context.HttpContext.User?.Identity?.Name; 
    } 
} 

あなたは自分のStartup.csファイルにConfigureServicesメソッド内でパイプラインにこれ​​を注入する必要があるでしょう:最後に

services.AddTransient<UserResolverService>(); 

そして、 DbContextのコンストラクタ内でアクセスしてください:

public partial class ExampleContext : IExampleContext 
{ 
    private YourContext _context; 
    private string _user; 
    public ExampleContext(YourContext context, UserResolverService userService) 
    { 
     _context = context; 
     _user = userService.GetUser(); 
    } 
} 

次に、_userを使用して、自分のコンテキスト内で現在のユーザーを参照できるようにする必要があります。これは、現在の要求内で利用可能なあらゆるコンテンツを格納/アクセスするために容易に拡張することができる。

+5

戻り値の後にawaitキーワードを削除します。このように 'public string GetUser() { return _context.HttpContext.User?.Identity?.Name; } ' –

+5

今、IHttpContextAccessorはデフォルトでサービスに登録されていません。私たちはStartup.cs 'services.TryAddSingleton ();' –

関連する問題