2016-04-04 14 views
5

का उपयोग कर डीबीकॉन्टेक्स्ट में उपयोगकर्ता की जानकारी कैसे प्राप्त करें मैं कक्षा पुस्तकालय विकसित करने की कोशिश कर रहा हूं जिसमें मैं कस्टम DbContext लागू करना चाहता हूं। SaveChangesDbContext की विधि में, मुझे ऑडिटिंग उद्देश्य के लिए वर्तमान उपयोगकर्ता की जानकारी (विभाग, उपयोगकर्ता नाम आदि) प्राप्त करने की आवश्यकता है। 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 इंजेक्शन और ( HttpContext.Items से जानकारी प्राप्त इस मामले DbContext निर्भर करता है में HttpContext.Items का उपयोग करना HttpContext, क्या यह सही है?)
  • HttpContext.Items के बजाय थ्रेडस्टैटिक ऑब्जेक्ट का उपयोग करना और obje से जानकारी प्राप्त करना सीटी

प्रश्न (मैं कुछ पदों कि ThreadStatic सुरक्षित नहीं है पढ़ने के लिए): जो मेरे मामले में सबसे उपयुक्त है? क्या आप एक और तरीका सुझाते हैं?

+1

इसे लागू करने का प्रयास करें। धन्यवाद। –

+0

कि वास्तव में अच्छा तरीका है, मैं करूँगा लगता है के रूप में IHttpContextAccessor पर निर्भर कर सकते हैं अपने DbContext उस पर निर्भर की –

उत्तर

12

मैं एक दृष्टिकोण इस के समान है कि this blog post में कवर किया जाता है और मूल रूप से एक सेवा है जो निर्भरता इंजेक्शन का उपयोग एक विशेष संदर्भ में HttpContext (और अंतर्निहित उपयोगकर्ता जानकारी) सुई होगा, या फिर भी आप इसे उपयोग करने के लिए पसंद करेंगे बनाने शामिल है कार्यान्वित ।

एक बहुत ही बुनियादी कार्यान्वयन कुछ इस तरह दिख सकता है:

services.AddTransient<UserResolverService>(); 

और फिर अंत में:

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 विधि के भीतर पाइप लाइन में इस इंजेक्षन करने की आवश्यकता होगी , बस इसे अपने निर्दिष्ट DbContext:

public partial class ExampleContext : IExampleContext 
{ 
    private YourContext _context; 
    private string _user; 
    public ExampleContext(YourContext context, UserResolverService userService) 
    { 
     _context = context; 
     _user = userService.GetUser(); 
    } 
} 
के निर्माता के भीतर पहुंचें

फिर आप अपने संदर्भ में वर्तमान उपयोगकर्ता को संदर्भित करने के लिए _user का उपयोग करने में सक्षम होना चाहिए। वर्तमान अनुरोध के भीतर उपलब्ध किसी भी सामग्री को स्टोर/एक्सेस करने के लिए इसे आसानी से बढ़ाया जा सकता है।

बजाय अपने DbContext में सीधे IHttpContextAccessor पर निर्भरता लेने क्यों AuditLogger की तरह एक सेवा वर्ग नहीं और, AuditLogger अपने स्वयं के आंतरिक कार्यान्वयन विस्तार
+5

इस 'सार्वजनिक स्ट्रिंग GetUser() { वापसी _context.HttpContext.User ?Identity? नाम; } ' –

+5

अब IHttpContextAccessor डिफ़ॉल्ट रूप से सेवाओं में पंजीकृत नहीं है। हमें इसे स्टार्टअप सीएस सेवाओं में मैन्युअल रूप से तार करना होगा। ट्राएडिंग सिंगलेटन (); ' –

संबंधित मुद्दे