क्या एक सिंगलटन के रूप में लकड़हारा होना एक अच्छा अभ्यास है?


81

मुझे लकड़हारे को कंस्ट्रक्टर के पास जाने की आदत थी, जैसे:

public class OrderService : IOrderService {
     public OrderService(ILogger logger) {
     }
}

लेकिन यह काफी कष्टप्रद है, इसलिए मैंने इसे कुछ समय के लिए एक संपत्ति का उपयोग किया है:

private ILogger logger = NullLogger.Instance;
public ILogger Logger
{
    get { return logger; }
    set { logger = value; }
}

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

    Infrastructure.Logger.Info("blabla");

अद्यतन: जैसा कि मेरलिन ने ठीक से देखा, मुझे उल्लेख करना चाहिए, कि पहले और दूसरे उदाहरण में मैं DI का उपयोग कर रहा हूं।



1
मैं जो उत्तर देख रहा हूं, उससे ऐसा लगता है जैसे लोगों को एहसास ही नहीं हुआ कि आप उन दोनों उदाहरणों में इंजेक्शन लगा रहे हैं। क्या आप इस प्रश्न में स्पष्ट कर सकते हैं? मैंने कुछ की देखभाल करने के लिए टैग जोड़े हैं।
मेरलिन मॉर्गन-ग्राहम

1
इस लेख की टिप्पणियाँ पढ़ें निर्भरता इंजेक्शन मिथक: Google के Miško Hevery द्वारा संदर्भ पासिंग जो परीक्षण और निर्भरता इंजेक्शन में बहुत बड़ा है। वह कहते हैं कि लॉगिंग एक अपवाद की तरह है जहां एक सिंगलटन ठीक है जब तक आपको लॉगर के उत्पादन का परीक्षण करने की आवश्यकता नहीं होती है (जिस स्थिति में डीआई)।
उपयोगकर्ता

जवाबों:


35

यह भी गुस्सा हो रहा है - यह DRY नहीं है

यह सच है। लेकिन वहाँ केवल इतना है कि आप एक क्रॉस-कटिंग चिंता के लिए कर सकते हैं जो आपके पास हर प्रकार से व्याप्त है। आपको हर जगह लकड़हारे का उपयोग करना होगा, इसलिए आपके पास उन प्रकारों पर संपत्ति होनी चाहिए।

तो देखते हैं कि हम इसके बारे में क्या कर सकते हैं।

एकाकी वस्तु

सिंगलनेट भयानक हैं <flame-suit-on>

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

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

यदि आप ऐसा करते हैं, तो का उपयोग कर अन्य लोगों के उत्तर देखें पैटर्न (विवरण देखें), और एक (resetable) सिंगलटन दर्ज की उन कारखाने के बजाय एक सिंगलटन लकड़हारा उदाहरण।Registry

ऐसे अन्य विकल्प हैं जो बिना किसी समझौते के बस काम कर सकते हैं, इसलिए आपको पहले उनकी जांच करनी चाहिए।

विजुअल स्टूडियो कोड स्निपेट

आप उस दोहराए गए कोड के प्रवेश को तेज करने के लिए विज़ुअल स्टूडियो कोड स्निपेट्स का उपयोग कर सकते हैं । आप कुछ टाइप करने में सक्षम होंगे loggertab, और कोड जादुई रूप से आपके लिए दिखाई देगा।

बंद करने के लिए AOP का उपयोग करना

आप आस्पेक्ट ओरिएंटेड प्रोग्रामिंग (AOP) फ्रेमवर्क जैसे PostSharp जैसे कुछ को ऑटो-जेनरेट करने के लिए उस प्रॉपर्टी इंजेक्शन कोड को थोड़ा खत्म कर सकते हैं ।

ऐसा कुछ ऐसा हो सकता है जब आप कर रहे हों:

[InjectedLogger]
public ILogger Logger { get; set; }

आप विधि विधि अनुरेखण नमूना कोड का उपयोग भी स्वचालित रूप से विधि प्रवेश और निकास कोड का पता लगाने के लिए कर सकते हैं, जो सभी लकड़हारा गुणों को एक साथ जोड़ने की आवश्यकता को समाप्त कर सकता है। आप एक वर्ग स्तर पर विशेषता लागू कर सकते हैं, या नाम स्थान चौड़ा:

[Trace]
public class MyClass
{
    // ...
}

// or

#if DEBUG
[assembly: Trace( AttributeTargetTypes = "MyNamespace.*",
    AttributeTargetTypeAttributes = MulticastAttributes.Public,
    AttributeTargetMemberAttributes = MulticastAttributes.Public )]
#endif

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

1
C ++ डरावनी कहानी के लिए @NickRosencrantz +1; मुझे एक-दो मिनट बिताने में बहुत अच्छा लगता है, क्योंकि एकल गीतों की टेररिज़्म को केवल स्क्रॉल करने के लिए और "हाहा लोल कम से कम मुझे उनकी समस्याएं नहीं हैं।"
डोमोनिक

32
</flame-suit-on> मुझे नहीं पता कि आप 5 साल तक एक लौ सूट में कैसे रहे लेकिन मुझे उम्मीद है कि इससे मदद मिलेगी।
ब्रेनन स्प्रिमोंट

39

मैंने अपने निर्भरता इंजेक्शन कंटेनर में एक लकड़हारा उदाहरण रखा है, जो तब लकड़हारा को उन वर्गों में इंजेक्ट करता है जिन्हें एक की आवश्यकता होती है।


8
क्या आप अधिक विस्तार से बताएंगे? क्योंकि मुझे लगता है कि मैंने प्रश्न में 1 और 2 कोड नमूनों में क्या किया / किया है?
गिदरीस

2
"उपयोग" वर्ग मूल रूप से वही होगा जो आपके पास पहले से है। हालांकि, वास्तविक मूल्य, आपकी कक्षा को मैन्युअल रूप से दिए जाने की आवश्यकता नहीं है, क्योंकि DI कंटेनर आपके लिए ऐसा करता है। यह एक परीक्षण में लकड़हारे को बदलने के लिए बहुत आसान बनाता है, क्योंकि एक स्थिर सिंगलटन लकड़हारा होने की तुलना में।
डैनियल रोज

2
उत्थान नहीं है, भले ही यह सही उत्तर (IMO) है, क्योंकि ओपी ने पहले ही कहा था कि वे ऐसा कर रहे थे। इसके अलावा, इस बनाम एक सिंगलटन का उपयोग करने के लिए आपका औचित्य क्या है? उन मुद्दों के बारे में जो ओपी दोहराव वाले कोड के साथ है - इस जवाब से कैसे पता चलता है?
मेरलिन मॉर्गन-ग्राहम

1
@ मर्लिन ओपी ने कहा कि उनके पास कंस्ट्रक्टर के हिस्से के रूप में या सार्वजनिक संपत्ति के रूप में एक लकड़हारा है। उन्होंने यह नहीं बताया कि उनके पास सही मूल्य का डीआई कंटेनर है। इसलिए मैं मान रहा हूं कि ऐसा नहीं है। हां, कुछ दोहराया कोड है (लेकिन एक जिम्मेदार ऑटो संपत्ति के साथ, उदाहरण के लिए, यह बहुत कम है), लेकिन IMHO यह स्पष्ट रूप से निर्भरता दिखाने के लिए बेहतर है कि इसे (वैश्विक) सिंगलटन के माध्यम से छिपाया जाए।
डेनियल रोज

1
@ डैनियलरोज़: और आपने अपना दिमाग बदल दिया है "यह स्पष्ट रूप से निर्भरता दिखाने के लिए बेहतर है कि इसे (वैश्विक) सिंगलटन के माध्यम से छिपाने के लिए"। +1
मेरलिन मॉर्गन-ग्राहम

25

अच्छा प्रश्न। मेरा मानना ​​है कि ज्यादातर प्रोजेक्ट्स लकड़हारा एक सिंगलटन है।

कुछ विचार बस मेरे दिमाग में आते हैं:

  • उपयोग ServiceLocator (या एक अन्य निर्भरता इंजेक्शन कंटेनर अगर आप पहले से ही किसी भी उपयोग करते हुए) जो इस तरह से आप ServiceLocator के माध्यम से लकड़हारा या यहां तक कि कई अलग अलग वालों और शेयर का दृष्टांत सकता है, जो स्पष्ट रूप से एक सिंगलटन होगा में, सेवाओं / वर्गों में हिस्सा लकड़हारा करने की अनुमति देता , नियंत्रण के व्युत्क्रम के कुछ प्रकार । यह दृष्टिकोण आपको एक लकड़हारा तात्कालिकता और आरंभीकरण प्रक्रिया पर बहुत लचीलापन देता है।
  • यदि आपको लगभग हर जगह लकड़हारा चाहिए - Objectप्रकार के लिए विस्तार विधियों को लागू करें ताकि प्रत्येक वर्ग लकड़हारा के तरीकों को कॉल करने में सक्षम हो LogInfo(), जैसे LogDebug(),LogError()

क्या आप अधिक विशिष्ट हो सकते हैं, जो आपके मन में विस्तार के तरीकों के बारे में बात कर रहे थे? ServiceLocator का उपयोग करने के बारे में, मैं सोच रहा हूं कि संपत्ति के इंजेक्शन की तुलना में यह बेहतर क्यों होगा, जैसे कि नमूना 2 में।
Giedrius

1
@Giedrius: विस्तार के तरीकों के बारे में - आप की तरह विस्तार तरीकों बना सकते हैं public static void LogInfo(this Object instance, string message)ताकि प्रत्येक वर्ग यह, लेने हैं के बारे में ServiceLocator- यह आप नहीं एक सिंगलटन एक नियमित रूप से वर्ग उदाहरण के रूप में लकड़हारा होने है, तो आप ज्यादा लचीलापन देना होगा की अनुमति देता है
SLL

@Giedrius यदि आप आईओसी को कंस्ट्रक्टर इंजेक्शन और डीआई फ्रेमवर्क को लागू करते हैं जो आप उपयोग कर रहे हैं, तो आपके कंस्ट्रक्टरों को स्कैन करने और स्वचालित रूप से अपनी निर्भरता को इंजेक्ट करने की क्षमता है (यदि आप अपने डीआई फ्रेमवर्क बूटस्ट्रैप प्रक्रिया पर उन निर्भरता को कॉन्फ़िगर करते हैं), तो जिस तरह से आपने उपयोग किया है क्या यह ठीक काम करेगा। साथ ही अधिकांश DI फ्रेमवर्क से आपको प्रत्येक ऑब्जेक्ट के जीवन चक्र का दायरा निर्धारित करने की अनुमति मिलनी चाहिए।
जीआर 7

7
ServiceLocator DI कंटेनर नहीं है। और इसे विरोधी पैटर्न माना जाता है।
पियोट्र पर्क

1
ओपी पहले से ही डीआई कंटेनर के साथ डीआई का उपयोग कर रहा है। पहला उदाहरण ctor injection है, दूसरा गुण इंजेक्शन है। उनका संपादन देखें।
मर्लिन मॉर्गन-ग्राहम

16

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

रजिस्ट्री स्वयं लॉग का उपयोग करने के लिए सरल वाक्यविन्यास देने के लिए एक स्थिर वर्ग हो सकती है:

Registry.Logger.Info("blabla");

6
पहली बार मैं रजिस्ट्री पैटर्न में आया हूं। क्या यह कहना अति-सरलीकरण है कि यह मूल रूप से सभी वैश्विक चर और कार्य एक छतरी के नीचे हैं?
जोएल गुडविन

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

5
रजिस्ट्री और ServiceLocator बहुत अधिक एक और समान हैं। अधिकांश आईओसी चौखटे रजिस्ट्री के कार्यान्वयन के मूल में हैं।
माइकल ब्राउन

1
@ माइकबर्न: ऐसा लगता है कि डि-कंटेनर (आंतरिक रूप से, सर्विस लोकेटर पैटर्न) एक इंस्टेंस्ड क्लास हो सकता है, जबकि रजिस्ट्री पैटर्न एक स्टैटिक क्लास का उपयोग करता है। क्या यह सही है?
मेरलिन मॉर्गन-ग्राहम

1
@MichaelBrown अंतर यह है कि आप रजिस्ट्री / सेवा लोकेटर का उपयोग करते हैं। यदि यह केवल रचना जड़ में है, तो यह ठीक है; यदि आप कई स्थानों पर उपयोग करते हैं, तो यह खराब है।
ओनूर

10

एक सादा सिंगलटन एक अच्छा विचार नहीं है। यह लकड़हारे को बदलना कठिन बनाता है। मैं अपने लॉगर के लिए फ़िल्टर का उपयोग करता हूं (कुछ "शोर" कक्षाएं केवल चेतावनी / त्रुटियां लॉग कर सकती हैं)।

मैं लकड़हारा कारखाने के लिए प्रॉक्सी पैटर्न के साथ संयुक्त सिंगलटन पैटर्न का उपयोग करता हूं:

public class LogFactory
{
    private static LogFactory _instance;

    public static void Assign(LogFactory instance)
    {
        _instance = instance;
    }

    public static LogFactory Instance
    {
        get { _instance ?? (_instance = new LogFactory()); }
    }

    public virtual ILogger GetLogger<T>()
    {
        return new SystemDebugLogger();
    }
}

यह मैं बनाने के लिए एक की अनुमति देता है FilteringLogFactoryया सिर्फ एक SimpleFileLogFactoryकिसी भी कोड को बदलने (और इसलिए खुला / बंद सिद्धांत का पालन करने) के बिना।

नमूना विस्तार

public class FilteredLogFactory : LogFactory
{
    public override ILogger GetLogger<T>()
    {
        if (typeof(ITextParser).IsAssignableFrom(typeof(T)))
            return new FilteredLogger(typeof(T));

        return new FileLogger(@"C:\Logs\MyApp.log");
    }
}

और नए कारखाने का उपयोग करने के लिए

// and to use the new log factory (somewhere early in the application):
LogFactory.Assign(new FilteredLogFactory());

अपनी कक्षा में जिसे लॉग इन करना चाहिए:

public class MyUserService : IUserService
{
    ILogger _logger = LogFactory.Instance.GetLogger<MyUserService>();

    public void SomeMethod()
    {
        _logger.Debug("Welcome world!");
    }
}

मेरी पिछली टिप्पणी को कभी न भूलें। मुझे लगता है कि मैं देख रहा हूं कि आप यहां क्या कर रहे हैं। क्या आप वास्तव में इस पर लॉग इन करने वाले वर्ग का उदाहरण प्रदान कर सकते हैं?
मर्लिन मॉर्गन-ग्राहम

+1; निश्चित रूप से एक नग्न सिंगलटन धड़कता है :) फिर भी स्थिर वस्तुओं का उपयोग करने के कारण स्थैतिक-स्कोप / थ्रेडिंग मुद्दों के लिए कुछ मामूली युग्मन और क्षमता है, लेकिन मुझे लगता है कि वे दुर्लभ हैं (आप Instanceएप्लिकेशन रूट में सेट करना चाहते हैं और मुझे नहीं पता है आप इसे रीसेट क्यों करेंगे)
मेरलिन मॉर्गन-ग्राहम

1
@ मेरलिनमर्गन-ग्राहम: यह संभावना नहीं है कि आप इसे स्थापित करने के बाद एक कारखाना बदलते हैं। कार्यान्वयन कारखाने में कोई भी संशोधन किया जाएगा और आपको उस पर पूर्ण नियंत्रण प्राप्त होगा। मैं सिंगलटन के लिए एक सार्वभौमिक समाधान के रूप में इस पैटर्न की सिफारिश नहीं करूंगा, लेकिन यह कारखानों के लिए अच्छी तरह से काम करता है क्योंकि उनके एपीआई शायद ही कभी बदलते हैं। (इसलिए आप इसे प्रॉक्साइड एब्सट्रैक्ट फैक्ट्री सिंगलटन,
हेहे

3

.NET में बुक डिपेंडेंसी इंजेक्शन है। आपको क्या चाहिए इसके आधार पर आपको अवरोधन का उपयोग करना चाहिए।

इस पुस्तक में कंसट्रक्टर इंजेक्शन, प्रॉपर्टी इंजेक्शन, मेथड इंजेक्शन, एम्बिएंट कॉनटेक्स्ट, इंटरसेप्शन का उपयोग करने का निर्णय लेने में मदद करने के लिए एक आरेख है।

इस आरेख का उपयोग करने का एक कारण यह है:

  1. क्या आपके पास निर्भरता है या इसकी आवश्यकता है? - जरूरत है
  2. क्या यह क्रॉस-कटिंग की चिंता है? - हाँ
  3. क्या आपको इससे उत्तर की आवश्यकता है? - नहीं

अवरोधन का उपयोग करें


मुझे लगता है कि प्रथम दृष्टया प्रश्न में एक गलती है (मुझे लगता है कि यह होना चाहिए "क्या आपके पास निर्भरता है या इसकी आवश्यकता है?")। वैसे भी, इंटरसेप्शन का उल्लेख करने के लिए +1, विंडसर में इसकी संभावनाओं का अध्ययन करना और यह बहुत दिलचस्प लगता है। यदि आप इसके अतिरिक्त उदाहरण दे सकते हैं कि आप कल्पना करते हैं कि यह यहाँ कैसे फिट होगा, तो यह बहुत अच्छा होगा।
गिदरीस

+1; दिलचस्प सुझाव - प्रकारों को छूने के बिना मूल रूप से एओपी जैसी कार्यक्षमता देगा। मेरी राय (जो बहुत सीमित जोखिम पर आधारित है ) यह है कि प्रॉक्सी पीढ़ी के माध्यम से अवरोधन (एक DI पुस्तकालय AOP विशेषता-आधारित पुस्तकालय के विपरीत प्रदान कर सकता है) काले जादू की तरह लगता है, और यह समझने के लिए कुछ हद तक कठिन बना सकता है कि क्या है चल रहा। क्या यह मेरी समझ में गलत है कि यह कैसे गलत है? किसी को भी इसके साथ एक अलग अनुभव था ? क्या यह कम डरावना है जितना लगता है?
मेरलिन मॉर्गन-ग्राहम

2
यदि आपको ऐसा लगता है कि इंटरसेप्शन बहुत 'जादू' है, तो आप सिर्फ डेकोरेटर डिजाइन पैटर्न का उपयोग कर सकते हैं और इसे स्वयं लागू कर सकते हैं। लेकिन इसके बाद आप शायद महसूस करेंगे कि यह समय की बर्बादी है।
पियोट्र पर्क

मैंने मान लिया कि यह सुझाव लॉगिंग में प्रत्येक कॉल को स्वचालित रूप से लपेट देगा, क्योंकि क्लास लॉग को स्वयं बनाने (बनाने) के विपरीत है। क्या वो सही है?
मर्लिन मॉर्गन-ग्राहम

हाँ। यही डेकोरेटर करता है।
पियोट्र पेरक

0

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

Logger::initialize ("filename.log", Logger::LEVEL_ERROR); // only need to be called once in your application

Logger::log ("my error message", Logger::LEVEL_ERROR); // to be used in every method where needed

-1

यदि आप लॉगिंग के लिए एक अच्छा समाधान देखना चाहते हैं, तो मेरा सुझाव है कि आप Google ऐप इंजन को अजगर के साथ देखें जहां लॉगिंग उतना ही सरल है import loggingऔर फिर आप बस logging.debug("my message")याlogging.info("my message") जो इसे वास्तव में उतना ही सरल रखता है जितना चाहिए।

जावा के पास लॉगिंग के लिए एक अच्छा समाधान नहीं है अर्थात लॉग 4 जे से बचना चाहिए क्योंकि यह व्यावहारिक रूप से आपको सिंगलटन का उपयोग करने के लिए मजबूर करता है जैसा कि यहां बताया गया है कि "भयानक" है और मुझे लॉगिंग आउटपुट को केवल एक बार लॉगिंग आउटपुट बनाने की कोशिश करने के साथ भयानक अनुभव हुआ है जब मुझे संदेह होता है कि डबल लॉगिंग का कारण यह था कि मेरे पास एक ही वर्चुअल मशीन (!) में दो क्लास लोडर में लॉगिंग ऑब्जेक्ट का एक सिंगलटन है!

मैं सी # के लिए इतना विशिष्ट नहीं होने के लिए आपके क्षमा को भीख माँगता हूँ, लेकिन मैंने सी # के साथ जो समाधान देखा है, उसी तरह के जावा को देखें जहां हमारे पास लॉग 4 जे था और हमें इसे एक सिंगलटन भी बनाना चाहिए।

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

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


C # एक सिंगलटन (या एक स्थिर वर्ग, जो संभवतः समान है, संभवतः बदतर है, क्योंकि यह और भी कम लचीलापन प्रदान करता है) में समान कोड नहीं है? using Logging; /* ... */ Logging.Info("my message");
मर्लिन मॉर्गन-ग्राहम

और यदि आप अपने लॉगर्स को इंजेक्ट करने के लिए निर्भरता इंजेक्शन का उपयोग करते हैं, तो आप लॉग 4j पैटर्न के साथ एकल से बच सकते हैं। बहुत सारे पुस्तकालय ऐसा करते हैं। आप रैपर का भी उपयोग कर सकते हैं जो एक सामान्य इंटरफेस प्रदान करते हैं ताकि आप अपने लॉगिंग कार्यान्वयन को बाद की तारीख में बदल सकें , जैसे netcommon.sourceforge.net या DI कंटेनर लाइब्रेरी जैसे कि कैसल.हिंडर्स या निनजेक्ट द्वारा प्रदान किए गए एक्सटेंशन में से एक
मॉर्गन-ग्राहम

यही समस्या है! logging.info("my message")हैलो वर्ल्ड की तुलना में अधिक जटिल कार्यक्रम में कोई भी कभी भी उपयोग नहीं करता है। आमतौर पर आप लॉगर को इनिशियलाइज़ करने के लिए बहुत सारे बॉयलरप्लेट करते हैं - फॉर्मैटर, लेवल को सेट करना, दोनों फाइल और कंसोल रिलेटर्स को सेट करना। यह कभी नहीं है logging.info("my message")!
द गॉडफादर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.