2012-03-13 21 views
5

सामान्य रूप से विधियों के साथ कक्षाओं का तात्कालिकता, लेकिन कोई फ़ील्ड या गुण नहीं है, बहुत अधिक उपर है?विधियों के साथ कक्षा तत्काल कितनी तेजी से है, लेकिन कोई फ़ील्ड या गुण नहीं है?

मैं एक एएसपी.नेट एमवीसी अनुप्रयोग विकसित कर रहा हूं जो कन्स्ट्रक्टर इंजेक्शन का उपयोग करता है और कुछ नियंत्रकों तक अब तक 10 निर्भरताएं हैं। लेकिन निर्भरता की उच्च संख्या के कारण, मैं एक IMyAppServiceProvider इंटरफेस और वर्ग है कि सभी निर्भरता के लिए जेनेरिक पहुँच प्रदान करता है के लिए DependencyResolver के माध्यम से MVC में सहारा, 3.

मैं अपने सभी आवेदन विशिष्ट कोड बाहर फट और एक Gist के साथ बनाया मेरा मूल सेटअप (इसमें नीचे उल्लिखित बेसकंट्रोलर सेटअप शामिल नहीं है)।

मैंने बेसकंट्रोलर क्लास भी बनाया जो IMyAppServiceProvider स्वीकार करता है। सभी नियंत्रक इस बेस क्लास से प्राप्त होते हैं। बेस क्लास IMyAppServiceProvider ऑब्जेक्ट लेता है और सभी विभिन्न सेवाओं के लिए चर सुरक्षित करता है। कोड इस तरह कुछ दिखता है:

public class BaseController 
{ 
    protected IService1 _service1; 
    protected IService2 _service2; 
    protected IService3 _service3; 
    // ... 

    public BaseController(IMyAppServiceProvider serviceProvider) 
    { 
     _service1 = serviceProvider.GetService<IService1>; 
     _service2 = serviceProvider.GetService<IService2>; 
     _service3 = serviceProvider.GetService<IService3>; 
     // ... 
    } 
} 

यह नियंत्रकों के लिए कोड "स्क्केकी क्लीन" बनाता है। कोई निजी/संरक्षित चर नहीं, कन्स्ट्रक्टर में कोई असाइनमेंट नहीं है, और सेवाओं को बेस क्लास संरक्षित चर द्वारा संदर्भित किया जाता है। हालांकि, प्रत्येक अनुरोध प्रत्येक एप्लिकेशन को तत्काल करेगा जो मेरा एप्लिकेशन उपयोग करता है, चाहे वह विशिष्ट नियंत्रक उन सभी का उपयोग करता हो या नहीं।

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

+2

हमेशा के रूप में, प्रोफ़ाइल पहले। हालांकि, मुझे लगता है कि निर्भरताओं को हल करना उनको तत्काल करने की तुलना में धीमी गति के आदेश है। –

+0

@insta वाह, मैंने पेड़ों के माध्यम से जंगल नहीं देखा। लेकिन निनजेक्ट और/या अन्य आईओसी कंटेनर कैश निर्भरता को हल करते हैं? –

+1

मैंने नीचे एक उत्तर जोड़ा जो आपकी मदद कर सकता है ... मैंने पहले इस सटीक समस्या में भाग लिया है। अधिकांश लोग (स्वयं शामिल) यह नहीं जानते कि आप कंट्रोलर फैक्टरी एएसपी.नेट एमवीसी नियंत्रकों को बनाने के लिए उपयोग कर सकते हैं। एक कस्टम एक आपके आईओसी कंटेनर को कसकर एकीकृत कर सकता है और निर्भरता को स्पूल कर सकता है क्योंकि उनकी आवश्यकता होती है। –

उत्तर

7

हर अनुरोध हर एक सेवा है कि मेरे आवेदन का उपयोग करता है, या नहीं, विशिष्ट नियंत्रक उन सभी का उपयोग करता है का दृष्टांत होगा।

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

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

इन्स्टेन्शियशन की लागत के बारे में, अपने मामले में यह एक बड़ा फर्क नहीं है, लेकिन सामान्य रूप में भारी वस्तुओं की लागत कम करने के लिए प्रारंभ आप कर सकते हैं:

  • उपयोग Prototype patternकरने के लिए "निहित लागत से बचने मानक तरीके से एक नई वस्तु बनाने (जैसे, 'नए' कीवर्ड का उपयोग) जब यह किसी दिए गए आवेदन " (ग) के लिए महंगे है की Wikipedia
  • उपयोग Lazy Initialization सेवाओं के लिए जो की शुरू से ही आवश्यक नहीं हैं स्वामी ऑब्जेक्ट लाइफ टाइम, इसलिए उनको मांग पर शुरू किया जाएगा। चूंकि .NET Framework 4।0 yo Lazy(T) class
+0

अच्छा जवाब, लेकिन मैं खुद को थोड़ा सा बचाव करना चाहता हूं। मेरा नियंत्रक एपीआई अब बहुत साफ है क्योंकि मैंने सेवा निर्भरता में सभी निर्भरताओं को सारणीबद्ध किया है। मैं प्रत्येक नियंत्रक के लिए एक और विशिष्ट इंटरफ़ेस कर सकता था, लेकिन मेरे विशेष एप्लिकेशन/लोड के लिए, यह अधिक है। इसके अलावा, मैं रनटाइम त्रुटियों से पीड़ित नहीं हूं, क्योंकि मेरा यूनिट परीक्षण सुनिश्चित करता है कि कोड चलता है, और सही ढंग से चलता है। लेकिन मैं निर्भरता के बारे में जागरूकता की कमी के बारे में आपका मुद्दा देखता हूं। अब जब मैंने यह किया है, तो मेरे पास नियंत्रक की निर्भरताओं को जानने का कोई आसान तरीका नहीं है (मेरे अपने संदर्भ के लिए)। मैं अभी इसके साथ ठीक हूँ। –

+0

ठीक है, वैसे भी यह अच्छा है कि इस तरह के बिंदु को ध्यान में रखें – sll

2

में निर्मित का उपयोग कर सकते हैं मुझे लगता है कि आप जिस समाधान को ढूंढ रहे हैं वह एक कस्टम नियंत्रक फैक्ट्री का उपयोग करना है। इस तरह, बनाए गए प्रत्येक नियंत्रक की बिल्कुल निर्भरताएं होती हैं। स्ट्रक्चर मैप के लिए यहां एक है, weblogs.asp.net:

using StructureMap; 
public class StructureMapControllerFactory : DefaultControllerFactory { 

    protected override IController GetControllerInstance(Type controllerType) { 
     try { 
      return ObjectFactory.GetInstance(controllerType) as Controller; 
     } 
     catch (StructureMapException) { 
      System.Diagnostics.Debug.WriteLine(ObjectFactory.WhatDoIHave()); 
      throw; 
     } 
    } 
} 

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

    //Configure StructureMapConfiguration 
    // TODO: config structuremap   

    //Set current Controller factory as StructureMapControllerFactory 
    ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory()); 
} 
+0

उत्तर के लिए धन्यवाद, लेकिन मुझे लगता है कि मेरे पास पहले से ही यह है? पहले मैंने नियंत्रक के रचनाकारों को उनकी सेवा निर्भरताओं के लिए इंटरफेस स्वीकार करने के लिए सेटअप किया था। Ninject और यह बूट करने के लिए बूटस्ट्रैपर है। –

+0

फिर आधार नियंत्रक का बिंदु क्या है जो प्रत्येक निर्भरता लेता है? यदि आपके नियंत्रकों को केवल कन्स्ट्रक्टर तर्क लेने के लिए छीन लिया गया है, तो उन्हें आवश्यकता है, हालांकि वे आबादी वाले हैं, तो यह सबसे अच्छा है जो आप कर सकते हैं। –

+0

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