7

के साथ डोमेन मॉडल कक्षाओं में निर्भरता इंजेक्शन देना मैं एक एएसपी.नेट एमवीसी एप्लीकेशन बना रहा हूं जो डीएचडी (डोमेन ड्राइव डिजाइन) दृष्टिकोण का उपयोग करता है जो एनएचबीर्नेट द्वारा संचालित डेटाबेस एक्सेस के साथ होता है। मैं डोमेन मॉडल वर्ग (प्रशासक) है कि मैं के माध्यम से में एक निर्भरता इंजेक्षन करना चाहते हैं एक आईओसी कंटेनर ऐसे महल विंडसर, कुछ इस तरह के रूप में: आईओसी बुला बिनानिबर्ननेट (एएसपी.नेट एमवीसी + आईओसी)

public class Administrator 
{ 
    public virtual int Id { get; set; } 

    //.. snip ..// 

    public virtual string HashedPassword { get; protected set; } 

    public void SetPassword(string plainTextPassword) 
    { 
     IHashingService hasher = IocContainer.Resolve<IHashingService>(); 

     this.HashedPassword = hasher.Hash(plainTextPassword); 
    } 
} 

मैं मूल रूप से SetPassword विधि के लिए IHashingService इंजेक्षन करना चाहते हैं कंटेनर सीधे (क्योंकि यह एक आईओसी एंटी-पैटर्न होने का अनुमान है)। लेकिन मुझे यकीन नहीं है कि इसे करने के बारे में कैसे जाना है। मेरा प्रशासक ऑब्जेक्ट या तो new Administrator(); के माध्यम से तत्काल हो जाता है या यह NHibernate के माध्यम से लोड हो जाता है, तो मैं IHashingService को व्यवस्थापक वर्ग में कैसे इंजेक्ट करूँगा?

दूसरे विचारों पर, क्या मैं इस बारे में सही तरीके से जा रहा हूं? मैं अपने codebase से अटे पड़े होने से बचने के लिए उम्मीद कर रहा था ...

currentAdmin.Password = HashUtils.Hash(password, Algorithm.Sha512); 

... और बदले डोमेन मॉडल ही हैशिंग का ख्याल रखना और बड़े करीने से इसे दूर संपुटित मिलता है। मैं एक और डेवलपर को गलती से गलत एल्गोरिदम चुनने और शा 512 के रूप में कुछ पासवर्ड और कुछ एमडी 5 के रूप में कुछ और कुछ अलग नमक आदि के साथ कुछ पासवर्ड रखने की कल्पना कर सकता हूं। इसके बजाए डेवलपर्स लिख रहे हैं ...

currentAdmin.SetPassword(password); 

... तो वह उन विवरणों को दूर छुपाएगा और ऊपर सूचीबद्ध उन समस्याओं का ख्याल रखेगा?

उत्तर

5

वहाँ इतने पर यहां इसी तरह के सवाल पहले से ही कर रहे हैं:

Dependency injection with NHibernate objects

DI/IoC, NHibernate and help in getting them to work together

आप Interceptors का उपयोग करना होगा।कार्यान्वयन के लिए फैबियो Maulo पद पर एक नज़र डालें:

http://nhforge.org/blogs/nhibernate/archive/2008/12/12/entities-behavior-injection.aspx

+0

इंटरसेप्टर दिलचस्प लगते हैं, मैं उन्हें आज़मा दूंगा, धन्यवाद! –

1

क्या कोई कारण है कि आप Administrator कक्षा के निर्माता में IHashingService पास नहीं कर सकते हैं? इस तरह मैं निर्भरता को हल करूंगा।

public class Administrator 
{ 
    private readonly IHashingService _hashingService; 

    public Administrator(IHashingService hashingService) 
    { 
     _hashingService = hashingService; 
    } 

    // <snip> 

    public void SetPassword(string plainTextPassword) 
    { 
     this.HashedPassword = _hashingService.Hash(plainTextPassword); 
    } 
} 

# संपादित करें 1

तो एक मॉडल से खींच, विधि-स्तरीय इंजेक्शन का उपयोग कर प्रयास करें।

public void SetPassword(string plainText, IHashingService hasher) 
{ 
    if (hasher == null) throw new ArgumentNullException("hasher"); 
    this.HashedPassword = hasher.Hash(plainText); 
} 

# संपादित 2

इसके अलावा, क्यों नहीं यह अपने आप पर आसान बनाने के लिए और सिर्फ स्ट्रिंग पर एक विस्तार है?

public static class ExtensionsOfString 
{ 
    public static string Hash(this string s) 
    { 
     // hash with SHA256 
     return hashedString; 
    } 
} 

जबकि मुझे पता है निर्भरता इंजेक्शन का उपयोग करने का एक "बदली" कोड पहलू यह है कि, यह वास्तव में इस उदाहरण के लिए एक बड़ी बात नहीं है। आपको वास्तव में IPasswordEncryptionService की आवश्यकता नहीं है, जिस तरह से आपको, ICreditCardAuthorizationService की आवश्यकता होगी। यदि, किसी दिन, आप SHA256 से SHA512 तक अपने हैशिंग एल्गोरिदम को बदलते हैं, तो अब आप अपने डेटाबेस में प्रत्येक पासवर्ड को अमान्य कर देंगे।

+2

क्योंकि प्रशासक निबर्ननेट (यानी अगर यह डेटाबेस से व्यवस्थापक ऑब्जेक्ट लोड कर रहा है) द्वारा तत्काल प्राप्त किया जा सकता है। तो मैं सेवा को इंजेक्ट करने के लिए एनएचबीर्नेट कैसे प्राप्त करूं? यह थोड़ा सा है ' मैं अटक गया। –

+1

मैं जारेट्स के दूसरे संपादन से सहमत हूं। इस मामले में आप एक निर्भरता इंजेक्शन दे रहे हैं जो वहां नहीं होना चाहिए। – jfar

+1

मैं इस उदाहरण में सहमत हूं, शायद निर्भरता इंजेक्शन सबसे अच्छा तरीका नहीं है। लेकिन मेरे पास संभावित रूप से अन्य हो सकता है ऐसे मामले जहां इसकी आवश्यकता है जैसे कि ITaxCalculatorService, इसलिए यह जानना उपयोगी होगा कि भविष्य के संदर्भ के लिए इसे कैसे किया जाए। –

2

आप याद करने के लिए कैसे यह टुकड़ों में बांटा गया था की जरूरत है। ऐसा इसलिए है कि आप भविष्य में एक स्ट्रिंग को जांच सकते हैं और देख सकते हैं कि यह उसका पासवर्ड है या नहीं, यह हैश की कीमत के साथ। इसका मतलब है कि आपको अपनी वस्तु में एक enum या कुछ अन्य फ़ील्ड को स्टोर करने की आवश्यकता है जो आपके डेटाबेस में उपयोग की जाने वाली हैशिंग तंत्र को इंगित करता है।

अन्यथा, यदि आप अपना डिफ़ॉल्ट हैशिंग कार्यान्वयन बदलते हैं, तो आपके पुराने पुराने पासवर्ड अब अच्छे नहीं हैं, और आपके उपयोगकर्ता अपने सिर खरोंच कर देंगे क्योंकि उनके पासवर्ड अब काम क्यों नहीं करते हैं - और आप समाप्त हो जाएंगे एक IHashingService इंटरफ़ेस जो कोई लचीलापन प्रदान नहीं करता है (चूंकि हैशिंग कार्यान्वयन को अजीब नियमों को जोड़ने के बिना बदला नहीं जा सकता है, जैसे "2010-01-12 से पहले बनाए गए प्रशासकों के लिए इस हैश का उपयोग करें"), वास्तविक वास्तविक कारण के लिए मौजूद नहीं है।

कि अंत करने के लिए

, मैं उपयुक्त फ़ील्ड (एक enum, एक स्ट्रिंग IHashingService इंटरफेस, कुछ द्वारा दिया) जोड़ना होगा और या तो NHibernate मेरे लिए हैशिंग सेवा का दृष्टांत एक IUserType कार्यान्वयन के माध्यम से है, या मैं एक कारखाने का उपयोग करेंगे पैटर्न जहां आईओसी कंटेनर द्वारा कारखाने को ठोस उदाहरण प्रदान किए गए थे। यह जारेट के विधि-स्तर इंजेक्शन को एक समाधान के साथ जोड़ देगा जो पुन: हाइड्रेटेड ऑब्जेक्ट्स को आईओसी कंटेनर पर निर्भर किए बिना अपने हैशिंग कार्यान्वयन को खोजने की अनुमति देता है।

शुभकामनाएं!

1

या तो किसी भी आवेदन में पासवर्ड है (यदि आप किसी का उपयोग कर रहे हैं) या Administrator.SetPassword(..) पर प्रत्येक कॉल पर IHashingService कार्यान्वयन की आपूर्ति करें। मुझे लगता है कि इसे डबल प्रेषण कहा जाता था?

आप पर जोर देते हैं, तो डि-इन-इकाई समाधान, मैं इकाई पर [Configurable] विशेषता की घोषणा के द्वारा PostSharp AOP और PostSharp4Spring साथ ऐसा ही कुछ किया है, लेकिन समाधान Spring.Net के लिए है। अधिक जानकारी के लिए आप here देख सकते हैं। साथ ही, यदि आप डीआई कंटेनर से NHibernate को कॉन्फ़िगर कर रहे हैं, तो कंटेनर कॉन्फ़िगर करने से पहले आप एक इकाई को डीआई करने की कोशिश कर रहे रिकर्सन में पड़ सकते हैं। कंटेनर प्रारंभिकरण के दौरान इकाई निर्माण पर DI को दबाने के तरीके के साथ आपको एक साधारण स्थैतिक वर्ग की आवश्यकता है। उदाहरण के लिए एक उदाहरण प्रदान नहीं कर सकता है :(

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