15

तो मेरे पास एक विरासत वेबफॉर्म साइट है और इसे बनाए रखने में आसान बनाने पर काम कर रहा हूं। इसे चकित करना और इसे फिर से लिखना एक विकल्प नहीं है।एएसपी.NET वेबफॉर्म में निर्भरता इंजेक्शन का कहना क्यों मुश्किल है जब पेजहैंडलर फैक्ट्री और आईएचटीपी हैंडलर फैक्ट्री मौजूद है?

आईओसी स्पष्ट रूप से पहली चीजों में से एक है, लेकिन यह मुझे सेवा-लोकेटर पैटर्न और एक बुरा स्वाद के साथ छोड़ देता है, और यह सोचकर कि यह बेहतर किया जा सकता है या नहीं।

विभिन्न लोगों से मैंने ऑनलाइन बात की है और मुझे बताएं कि मैं एक एचटीपी मॉड्यूल के साथ संपत्ति-इंजेक्शन कर सकता हूं जो एक इंजेक्ट विशेषता या इसी तरह से सजाए गए गुणों के लिए पेज क्लास स्कैन करता है, लेकिन यह एक प्रतिबिंब हिट (कैश , लेकिन फिर भी) हर अनुरोध पर। आकर्षक नहीं

तो मैं अन्य विकल्पों को देख रहा था, और System.Web.IHttpHandlerFactory पर आया, जो स्पष्ट रूप से v2 के बाद से ढांचे में रहा है। कोई डिफ़ॉल्ट * .aspx हैंडलर को हटा सकता है और इसे httpHandlers web.config सेक्शन में कस्टम कार्यान्वयन का उपयोग करने वाले व्यक्ति के साथ प्रतिस्थापित कर सकता है।

तो, जिन लोगों से मैंने बात की है वे गूंगा नहीं हैं; मैंने सोचा कि मैं यहाँ पूछूंगा। क्या आईओसी-आधारित कार्यान्वयन के साथ वेबफॉर्म पेजहैंडलर फैक्ट्री को बदलने के साथ कोई गठिया है ...?

ऐसा लगता है कि यह, दोनों एक CreateHandler और ReleaseHandler विधि है, इसलिए जीवन शैली से संबंधित कंटेनर बना घटकों के लिए एक संदर्भ रखने से मेमोरी लीक एक समस्या नहीं होनी चाहिए ...

उत्तर

27
जिस तरह से

एएसपी.नेट डिजाइन किया गया है, Page कक्षाओं में एक डिफ़ॉल्ट कन्स्ट्रक्टर होना चाहिए। जब आप कन्स्ट्रक्टर इंजेक्शन का उपयोग करना चाहते हैं, तो इसके चारों ओर एक रास्ता है। आप डिफ़ॉल्ट निर्माता संरक्षित बनाने के लिए और एक भी सार्वजनिक निर्माता कि निर्भरता के रूप में इस लेता है जोड़ सकते हैं:

public partial class _Default : System.Web.UI.Page 
{ 
    private IUserService service; 

    protected _Default() 
    { 
    } 

    public _Default(IUserService service) 
    { 
     this.service = service; 
    } 
} 

यह आप एक कस्टम PageHandlerFactory बना सकते हैं और निर्माता में निर्भरता इंजेक्षन कर सकते हैं।

तो यह काम करता है, लेकिन हालांकि एक पकड़ है। _Default कक्षा जिसे आप परिभाषित करते हैं वह वास्तविक वर्ग एएसपी.NET उपयोग नहीं है। एएसपी.नेट एक नई कक्षा बनाता है जो _Default से विरासत में मिलता है। यह नई कक्षा .aspx फ़ाइल में मार्कअप के आधार पर नियंत्रण पदानुक्रम बनाता है। यह वर्ग इस तरह एक सा दिखता है:

public class ASPGeneratedDefault : _Default 
{ 
    public ASPGeneratedDefault() : base() 
    { 
    } 

    protected override void OnPreInit(object s, EventArgs e) 
    { 
      // Building up control hierarchy. 
    } 
} 

आप देख सकते हैं, कस्टम निर्माता ASP.NET द्वारा ASPGeneratedDefault में अधिरोहित नहीं किया गया है। इस वजह से डीआई ढांचे को हमारे लिए इस प्रकार का निर्माण करने का कोई तरीका नहीं है। इसके आस-पास का तरीका ASP.NET को हमारे लिए इस प्रकार का निर्माण करना है और उस मौजूदा उदाहरण पर _Default बेस क्लास के गैर-डिफ़ॉल्ट कन्स्ट्रक्टर का आह्वान करना है। चूंकि यह उदाहरण पहले से मौजूद है, हमें इसे प्रतिबिंब के साथ करना होगा और आंशिक विश्वास में चलने पर यह असफल हो जाएगा।

इसके अलावा, यह पृष्ठ कक्षाओं के लिए काम करता है, लेकिन पृष्ठ पर उपयोगकर्ता नियंत्रण के लिए नहीं। एएसपी.NET के कोड जेनरेटर नियंत्रण पदानुक्रम निर्माण प्रक्रिया के दौरान उनके डिफ़ॉल्ट कन्स्ट्रक्टर के साथ उन नियंत्रणों को समाचार देते हैं। जब आप इसे उनके लिए काम करना चाहते हैं, तो आपको उन नियंत्रणों की PreInit ईवेंट को हुक करने के लिए अपने कस्टम PageHandlerFactory की आवश्यकता है, क्योंकि पृष्ठ श्रेणी के निर्माण के दौरान, संबंधित नियंत्रण और उपयोगकर्ता नियंत्रण अभी तक नहीं बनाए गए हैं। हालांकि, उन पर PreInit ईवेंट पंजीकृत करने के लिए, आपको पृष्ठ नियंत्रण में उन नियंत्रणों को ढूंढना होगा, और फिर हमें पृष्ठ वर्ग पर प्रतिबिंबित करने की आवश्यकता है। चूंकि नियंत्रण गैर-सार्वजनिक उदाहरण फ़ील्ड में संग्रहीत होते हैं, फिर भी यह आंशिक विश्वास में काम नहीं करेगा।

चाहे कोई समस्या हो, आपका आवेदन आंशिक विश्वास में नहीं चल सकता है, लेकिन आपके .NET 4 के सुरक्षा मॉडल को काफी सरल बनाया गया है, इसलिए आंशिक विश्वास में वेब ऐप्स चलाने में बहुत आसान है और यह कुछ है जो मैं करने का प्रयास करता हूं।

टीएलडीआर; तो निष्कर्ष में, ऐसा करना संभव है (उदाहरण के लिए this example देखें), लेकिन एएसपी.नेट वेब फॉर्म ढांचे की सीमाओं के कारण, आपको इसे काम करने के लिए पूर्ण विश्वास में भाग लेने की आवश्यकता है।

अद्यतन माइक्रोसॉफ्ट ASP.NET नेट 4.0 के साथ शुरू (here पढ़ें) के लिए आंशिक विश्वास obsoleted गया है। तो उस दृष्टिकोण से, पूर्ण विश्वास से दूर रहना उपयोगी नहीं हो सकता है (आपको वैसे भी इसकी आवश्यकता होगी)।

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