2009-08-20 22 views
10

मैं यूनिट कंटेनर का उपयोग करने की कोशिश कर रहा हूं ताकि यूनिट को मेरे नियंत्रकों का परीक्षण करना आसान हो सके। मेरा नियंत्रक एक कन्स्ट्रक्टर का उपयोग करता है जो एक रेपॉजिटरी को इंटरफ़ेस स्वीकार करता है। Global.asax फ़ाइल में, मैं एक यूनिटीकॉन्टेनर फैक्ट्री को तुरंत चालू करता हूं और इसे एमवीसी ढांचे के साथ पंजीकृत करता हूं और फिर भंडार और उसके कार्यान्वयन को पंजीकृत करता हूं। मैंने नियंत्रक के सीटीओआर रिपोजिटरी पैरामीटर में [निर्भरता] विशेषता जोड़ा। यह सब ठीक काम करने लगता है, सिवाय इसके कि कभी-कभी कारखाने के GetControllerInstance (टाइप कंट्रोलर टाइप) को एक से अधिक बार बुलाया जाता है और नियंत्रक टाइप के रूप में एक शून्य तर्क पारित किया जाता है।एएसपी.नेट एमवीसी और एकता 1.2 कंटेनर प्रश्न

कारखाने के लिए पहला कॉल अवेज़ सही है और नियंत्रक टाइप "उत्पाद नियंत्रक" एक तर्क के रूप में पारित किया गया है। लेकिन कभी-कभी, कारखाने को नियंत्रक के लिए शून्य मूल्य के साथ प्रदर्शित करने के बाद दो बार बुलाया जाता है और मुझे यकीन नहीं है कि क्यों। जब नियंत्रक प्रकार का सही मान पारित किया जाता है कि "कॉल स्टैक" मुझे समझ में आता है, लेकिन जब एक शून्य पास हो जाती है, तो मुझे यकीन नहीं है कि कॉल क्यों कर रहा है या कौन। कोई विचार?

उदाहरण के लिए कोड और कॉल स्टैक नीचे दिखाए गए हैं।

कॉल स्टैक जब है काम करता है

Test.dll! Test.UnityHelpers.UnityControllerFactory.GetControllerInstance (System.Type controllerType = {नाम = "ProductsController" FullName = "Test.Controllers.ProductsController"}) लाइन 23 सी # Test.dll! Test._Default.Page_Load (वस्तु इस = {} ASP.default_aspx, System.EventArgs ई = {System.EventArgs}) लाइन 18 + 0x1A बाइट्स सी #

कॉल स्टैक जब शून्य controllerType में पारित हो जाता है

टेस्ट। डीएलएल! टेस्ट.इरिटीहेल्पर। यूंटा कंट्रोलर फैक्टरी.गेटकंट्रोलर इंस्टेंस (सिस्ट em.Type controllerType = नल) लाइन 27 सी #

सबसे पहले मैं एक UnityControllerFactory

public class UnityControllerFactory : DefaultControllerFactory 
{ 
    UnityContainer container; 

    public UnityControllerFactory(UnityContainer container) 
    { 
     this.container = container; 
    } 

    protected override IController GetControllerInstance(Type controllerType) 
    { 
     if (controllerType != null) 
     { 
      return container.Resolve(controllerType) as IController; 
     } 
     else 
     { 
      return null; // I never expect to get here, but I do sometimes, the callstack does not show the caller 
     } 
    } 
} 

अगला बनाया है, मैं निम्नलिखित कोड कंटेनर कारखाने

protected void Application_Start() 
    { 
     RegisterRoutes(RouteTable.Routes); 

     // Create Unity Container if needed 
     if (_container == null) 
     { 
      _container = new UnityContainer(); 
     } 

     // Instantiate a new factory 
     IControllerFactory unityControllerFactory = new UnityControllerFactory(_container); 

     // Register it with the MVC framework 
     ControllerBuilder.Current.SetControllerFactory(unityControllerFactory); 

     // Register the SqlProductRepository 
     _container.RegisterType<IProductsRepository, SqlProductRepository> 
      (new ContainerControlledLifetimeManager()); 
    } 

का दृष्टांत को Global.asax फ़ाइल जोड़ी ऐप में एक नियंत्रक

public class ProductsController : Controller 
{ 
    public IProductsRepository productsRepository; 

    public ProductsController([Dependency]IProductsRepository productsRepository) 
    { 
     this.productsRepository = productsRepository; 
    } 
} 
+0

क्या आप 100% निश्चित हैं कि यह लाइन शून्य नहीं लौट रही है: कंटेनर लौटाएं। रिसीव (नियंत्रक टाइप) आईकंट्रोलर के रूप में; ऐसा असंभव लगता है, लेकिन परिणामस्वरूप टाइप आईकंट्रोलर नहीं था या संकल्प कॉल विफल होने पर वह कास्ट आसानी से शून्य हो सकती थी। –

+0

हाय एंडरसन, जैसा कि आप कॉल स्टैक से देख सकते हैं, नल पास हो रहा है। मैंने डीबगर का उपयोग करके लाइन पर भी रोक दिया और यह कास्ट से पहले शून्य नहीं है। यह कॉल उस समय ढेर पर एकमात्र कार्य है। जो मैं भी समझ में नहीं आता। टेस्ट। डीएलएल! टेस्ट.यूरिटीहेल्पर.यूटी कंट्रोलर फैक्ट्री। गेट कंट्रोलर इंस्टेंस (सिस्टम। टाइप कंट्रोलर टाइप = नल) लाइन 27 सी # – Rick

+0

मैंने सोचा कि मैं आपके ढेर में देख रहा था, लेकिन मैं यह सुनिश्चित करने के लिए अपनी धारणाओं को देखना चाहता था। –

उत्तर

9

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

यह ऐसा करने का एकमात्र कारण नहीं है, हालांकि, लेकिन यह आम है।

करने के लिए उचित बात यह है कि मूल परिस्थितियों में इन परिस्थितियों में अनुरोध को संभालने की अनुमति दी जाएगी। यह आमतौर पर केवल एक साधारण फ़ाइल अनुरोध है और आपके ऊपर कोई प्रभाव नहीं होना चाहिए। ऐसा करने के लिए

सरल बात इस तरह गेट इसे करने के लिए होगा:

if (controllerType != null) 
    { 
     return container.Resolve(controllerType) as IController; 
    } 
    else 
    { 
     return base.GetControllerInstance(requestContext, controllerType); 
    } 

कि यह करना चाहिए।

यह देखने के लिए कि अनुरोध क्या है, आप यह देखने के लिए HttpContext.Current.Request की जांच कर सकते हैं कि आपके रूट में कौन सी फ़ाइल नहीं है। कई बार ऐसा कुछ नहीं है जिसे आप नियंत्रित करना चाहते हैं, लेकिन यह आपको यह जानकर बेहतर महसूस करेगा कि अनुरोध की उत्पत्ति क्या है।

+0

धन्यवाद उत्तर और सुझावों के लिए ..... – Rick

+2

मैंने आपका सुझाव लिया और HttpContext.Current.Request को देखा और देखा कि favicon.ico की तलाश में है। यह बताता है कि यह कभी-कभी क्यों काम करता है और दूसरों को नहीं। जब ब्राउज़र का एक exisiting उदाहरण खुला था, यह favicon.ico खोजने की कोशिश नहीं की थी। – Rick

+0

अरे, जानना अच्छा और खुश मैं मदद कर सकता था। –

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