2009-05-18 17 views
16

वर्तमान में मैं एक ActionFilter HttpContext से मौजूदा उपयोगकर्ताओं नाम हो जाता है और कार्रवाई जो इसे एक सेवा पद्धति पर उपयोग करता है में से गुजरता है। उदाहरण के लिए:ASP.NET MVC: HttpContext और निर्भरता इंजेक्शन

Service.DoSomething(userName); 

मैं अब नहीं कार्रवाई स्तर लेकिन नियंत्रक निर्माता स्तर पर ऐसा करने के लिए एक कारण है। वर्तमान में मैं नियंत्रक बनाने और सेवा इंजेक्ट करने के लिए संरचना मानचित्र का उपयोग कर रहा हूं। मैं की तरह कुछ में देख रहा हूँ:

public interface IUserProvider 
{ 
    string UserName { get; } 
} 

public class HttpContextUserProvider : IUserProvider 
{ 
    private HttpContext context; 

    public HttpContextUserProvider(HttpContext context) 
    { 
     this.context = context; 
    } 

    public string UserName 
    { 
     get 
     { 
      return context.User.Identity.Name; 
     } 
    } 
} 

कहा, मेरे आईओसी foo वास्तव में कमजोर है के रूप में इस पहली परियोजना मैं इस पर उपयोग किया है है।

तो मेरे सवाल का कैसे मैं संरचना मैप बता HttpContextUserProvider के लिए निर्माता में HttpContext में पारित करने के लिए कर सकते हैं ...? यह सिर्फ अजीब लगता है ... मुझे यकीन नहीं है कि HttpContext के बारे में कैसे सोचें।

उत्तर

8

एक अंतरफलक सार HttpContext.Current है जा रहे हैं। केवल तरीकों की जरूरत बताएं। GetUserName() में HttpContext.Current.User.Identity.Name कहेंगे कार्यान्वयन, उदाहरण के लिए। के रूप में संभव के रूप में पतली करें।

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

+0

आपका क्या मतलब है, "बैग के लिए सामान्य प्रकार पैराम जोड़ें"? दिलचस्प लगता है। –

+4

सत्र –

+3

पर मजबूत टाइप किए गए रैपर प्रदान करते हैं क्या आपके पास कोई नमूना कोड/लिंक है, यह दिलचस्प लगता है _ मैं थोड़ी नई हूं, इसलिए मैं इसे ठीक से समझ नहीं पा रहा हूं, किसी भी मदद/सलाह की सराहना की जाएगी ... – Haroon

2

शायद मैं कुछ बाहर छोड़ दिया, लेकिन इसके बाद के संस्करण जवाब मेरे लिए काम नहीं करता है (के बाद से हटा दिया गया है - यह अभी भी हालांकि एक उपयोगी जवाब था - यह पता चला एसएम बताने के लिए निर्माता तर्क पारित करने के लिए)। इसके बजाय यदि मैं करता हूं:

ObjectFactory.Initialize(x => 
{ 
    x.BuildInstancesOf<HttpContext>() 
     .TheDefault.Is.ConstructedBy(() => HttpContext.Current); 
    x.ForRequestedType<IUserProvider>() 
     .TheDefault.Is.OfConcreteType<HttpContextUserProvider>(); 
}); 

मुझे यह काम करने के लिए मिलता है। मैं पाने के बाद ऐसा किया: http://codebetter.com/blogs/jeremy.miller/archive/2008/03/20/if-you-need-something-in-structuremap-but-you-can-t-build-it-with-new.aspx


संपादित करें:

ब्राड का जवाब देने के लिए धन्यवाद मुझे लगता है कि मैं HttpContext पर एक बेहतर संभाल। उसका जवाब निश्चित रूप से काम करता है, मुझे यकीन नहीं है कि मुझे एक वर्ग के अंदर HttpContext.Current को कॉल करना पसंद है (ऐसा लगता है जैसे यह निर्भरता को छुपाता है, लेकिन मैं इस सामान पर एक विशेषज्ञ से बहुत दूर हूं)।

ऊपर कोड HttpContext जहाँ तक मैं बता सकता इंजेक्शन लगाने के लिए काम करना चाहिए। मैट हिनज ने उस बिंदु को जोड़ा जो उस बिंदु को इंगित करता है कि अगर मुझे HttpContext की आवश्यकता है तो उपयोगकर्ता है। Identity.Name, मेरा डिज़ाइन इसके बारे में स्पष्ट होना चाहिए (HttpContext के आस-पास एक इंटरफेस केवल मुझे जो चाहिए उसे उजागर करना)। मुझे लगता है कि यह एक अच्छा विचार है। प्रयोक्ता नाम:

बात मैं थोड़े मेरी सेवा वास्तव में महसूस किया केवल एक स्ट्रिंग पर निर्भर करने की जरूरत है दोपहर का भोजन खत्म हो गया है। यह IUserProvider पर निर्भर होने के कारण अधिक मूल्य नहीं हो सकता है। तो मुझे पता है कि मैं नहीं चाहता कि यह HttpContext पर निर्भर करे, और मुझे पता है कि मुझे एक स्ट्रिंग (उपयोगकर्ता नाम) की आवश्यकता है - मुझे यह देखने की ज़रूरत है कि क्या मैं अपने लिए यह कनेक्शन बनाने के लिए पर्याप्त स्ट्रक्चर मैप foo सीख सकता हूं। (सिरोकू का जवाब कहां से शुरू करना है, इस पर एक संकेत देता है लेकिन उसने इसे हटा दिया: *()

+0

laymens संदर्भ जब एक निर्माता HttpContext आईओसी HttpContext.Current के उदाहरण में पारित करेंगे की एक निर्भरता है में। और जब एक निर्माता के पास IUserProvider की निर्भरता है IoC HttpContextUserProvider का एक नया उदाहरण तत्काल करेगा और इसे निर्माता में पास कर देगा। –

+0

स्ट्रक्चर मैप इंटरफ़ेस अच्छी तरह से पढ़ता है। मेरा भ्रम है कि मैं दो भागों में सोचता हूं: 1) मैंने कभी भी ForRequestedType का उपयोग किया है - मुझे कैसे पता चलेगा कि BuildInstances को तोड़ना कब होगा (मैं शायद यह सिर्फ Google - आसान सवाल कर सकता हूं) 2) क्या मैं बस मंजूरी दे सकता हूं कि स्ट्रक्चर मैप जानता है कि HttpContext.Current कैसे प्राप्त करें? मुझे लगता है कि HttpContext मुझे थोड़ा उलझन में डालता है कि यह सिर्फ जादुई रूप से हर जगह चारों ओर तैरता प्रतीत होता है। मैं एक ऐसे स्रोत के बारे में नहीं सोच सकता जिसे मैं प्राप्त करने के लिए जा सकता हूं, जहां बाकी सब कुछ एक स्पष्ट स्रोत है। – anonymous

+0

वास्तव में मेरा समाधान काम नहीं करता - और एक कट्टर त्रुटि के साथ भी, आंतरिक अपवाद ने एक जेआईटी सीमा के बारे में कुछ कहा ... वाह – sirrocco

3

मुझे यकीन नहीं है कि आप परेशान क्यों हैं। ऐसा लगता है कि केवल HttpContext.Current का उपयोग HttpContextUserProvider में सही है करते हैं। तुम कभी एक अलग HttpContext में प्रतिस्थापन किया जाना है ...

+0

याहू ... मुझे नहीं लगता कि मुझे * HttpContext मिलता है। मुझे लगता है कि मुझे कन्स्ट्रक्टर के माध्यम से कुछ पारित करने के लिए उपयोग किया जाता है, जहां एचटीपीकॉन्टेक्स्ट सिर्फ विश्व स्तर पर दिखाई देता है? – anonymous

+0

ठीक है, वापसी HttpContext.Current.User.Identity.Name; और यह काम करता है। मुझे लगता है कि मैं यहां आगे बढ़ने पर थोड़ी धीमी हूं लेकिन वर्तमान में एचटीपी कॉनटेक्स्ट पर एक स्थैतिक संपत्ति है जिसे वर्तमान एचटीपी कॉन्टेक्स्ट को कैसे ढूंढना है, यह जानने की ज़िम्मेदारी है। केवल नकारात्मक पक्ष यह है कि आप (कम से कम नहीं सोचते) कन्स्ट्रक्टर इंजेक्शन के माध्यम से HttpContext के आधार पर स्पष्ट हो सकते हैं क्योंकि आप स्थिर संपत्ति या प्रकार में नहीं जा सकते हैं? आप IHttpContextProvider जैसे कुछ रैपर बना सकते हैं जो केवल HttpContext.Current देता है और फिर आपको पता होगा कि कुछ HttpContext पर निर्भर करता है? या वह गूंगा है। – anonymous

+0

आप एक सेवा परत कहने में HttpContext को इंजेक्ट कैसे करेंगे जो वेब का संदर्भ नहीं देता है, शायद हम कह सकते हैं कि यह उस केस केस परिदृश्य है, जहां रिकॉर्ड/डेटा सेट वर्तमान उपयोगकर्ता पर निर्भर करता है? (asp.net mvc2) ... – Haroon

9

ऐसा लगता है कि आपको HttpContextUserProvider के बजाय HttpContextBase का उपयोग करना चाहिए।यह HttpContext का आउट-ऑफ-बॉक्स अबास्ट्रक्शन है और आपको एक नकली बनाने, यूनिटटेस्ट लिखने और अपनी निर्भरताओं को इंजेक्ट करने की अनुमति देता है।

public class SomethingWithDependenciesOnContext 
{ 
    public SomethingWithDependenciesOnContext(HttpContextBase context) { 
     ... 
    } 

    public string UserName 
    { 
     get {return context.User.Identity.Name;} 
    } 
} 

ObjectFactory.Initialize(x => 
      x.For<HttpContextBase>() 
      .HybridHttpOrThreadLocalScoped() 
      .Use(() => new HttpContextWrapper(HttpContext.Current)); 

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

  • कोई संबंधित समस्या नहीं^_^