2010-05-17 17 views
5

मैं log4net उपयोग कर रहा हूँ, और हम अपने कोड में इस का एक बहुत कुछ है:कक्षा सजावटी स्थिर सदस्य घोषित करने के लिए (उदाहरण के लिए, log4net के लिए)?

public class Foo { 
    private static readonly ILog log = LogManager.GetLogger(typeof(Foo)); 
    .... 
} 

एक नकारात्मक पक्ष यह मतलब है कि हम सब कुछ खत्म हो यह 10 शब्द खंड को पेस्ट करते है, और हर अब और फिर किसी को कक्षा का नाम बदलने के लिए भूल जाता है।

public class Foo { 
    private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 
    ... 
} 

क्या यह संभव है इस परिभाषित करने के लिए एक डेकोरेटर लिखने के लिए: log4net FAQ भी इस विकल्प संभावना है, जो और भी अधिक वर्बोज़ है का उल्लेख है? मैं वास्तव में बस कहने के लिए करना चाहते हैं:

[LogMe] // or perhaps: [LogMe("log")] 
public class Foo { 
    ... 
} 

मैं अन्य भाषाओं में समान कार्य कर लेते हैं, लेकिन कभी नहीं की तरह सी # एक स्थिर संकलित भाषा। क्या मैं कक्षा के सदस्यों को सजावटी से परिभाषित कर सकता हूं?

संपादित करें: हे। मैं एक लिस्प प्रोग्रामर हूं। मैं भाषाओं को स्विच करने के सुझावों की सराहना करता हूं, लेकिन वास्तव में, अगर मैं बेहतर मेटाप्रोग्रामिंग क्षमताओं के लिए भाषाएं स्विच करने जा रहा था, तो मैं इसके बारे में आधा assed होने की बजाय Lisp के लिए सभी तरह से जाना होगा। दुर्भाग्य से एक अलग भाषा का उपयोग इस परियोजना पर एक विकल्प नहीं है।

उत्तर

1

Attributes .NET में सजावटी/सक्रिय घटक नहीं हैं जो कक्षा/सदस्य से जुड़े हुए हैं। विशेषताएं मेटा-डेटा हैं जिन्हें प्रतिबिंब के साथ पुनर्प्राप्त किया जा सकता है। सी # में कोई सजावटी जैसी सुविधा नहीं है, हालांकि एओपी समाधान हैं जो आप चाहते हैं के साथ .NET का विस्तार करते हैं। सबसे आसान समाधान शायद उस वर्ग को प्रत्येक वर्ग में कॉपी करने के लिए है।

+0

यह सच है, और मैं गलत टाइप करता हूं। फिर भी, मुझे लगता है कि मैं किसी तरह के वैश्विक प्रारंभिक हुक की उम्मीद कर रहा था जिसका उपयोग सदस्यों में गुणों को रूपांतरित करने के लिए किया जा सकता था। – Ken

5

यह एओपी - आस्पेक्ट ओरिएंटेड प्रोग्रामिंग के लिए बिल्कुल एक काम है। PostSharp पर एक नज़र डालें, यह एक .NET AOP ढांचा है, यह आपको वही करने की अनुमति देगा जो आप चाहते हैं।

यह पोस्ट-संकलन में आईएल कोड को संशोधित (या बुनाई) और सजावटी विधि में लॉगिंग पहलू जोड़कर काम करता है।

संपादित करें: ऐसा प्रतीत होता है कि पोस्टशर्प अब एक वाणिज्यिक उत्पाद है। यदि आप ओपन-सोर्स (फ्री) समाधान की तलाश में हैं, तो मैं LinFu AOP का सुझाव देता हूं।

0

यदि यह एएसपी.नेट या विंडोज फॉर्म है, तो आप केवल एक बेस पेज या बेस फॉर्म बना सकते हैं जो आपके सभी फॉर्म/पेज से निकलता है। आप इस सदस्य को उस स्तर पर घोषित कर सकते हैं और संभवतया आप जो चाहते हैं उसे प्राप्त कर सकते हैं।

+0

मुझे पूरी तरह से यकीन नहीं है कि वे क्या हैं। मैं बस सादा सी # का उपयोग कर रहा हूँ। – Ken

+0

केवल एक पंक्ति द्वारा कोड को कम करने के लिए एक निश्चित आधार वर्ग को उपclass * बहुत * खराब कोड गंध है! क्या होगा यदि आपको एक अलग, दिए गए, बेस क्लास को उप-वर्ग करने के लिए कक्षा की आवश्यकता है? टिम जर्विस के समाधान को देखें जो कम से कम उप-वर्ग की आवश्यकता नहीं है लेकिन एक इंटरफ़ेस का उपयोग करता है। – chiccodoro

0

आप शायद PostSharp, या अन्य पहलू ओरिएंटेड प्रोग्रामिंग टूल की सहायता से इसके लिए एक समाधान लागू कर सकते हैं।

बू में एक मैक्रो का उपयोग करके यह बहुत छोटा होगा, लेकिन इससे आपकी स्थिति में बहुत मदद नहीं मिलेगी।

0

शायद एक आसान तरीका एक अंतरफलक पर एक विस्तार विधि लिखने के लिए किया जाएगा, तो अपने वर्ग सिर्फ "लागू" करने की जरूरत है (लेकिन वास्तव में, क्योंकि विस्तार impl करता है) इंटरफेस

public class Foo : IGetLog<Foo> 
{ 

} 

विस्तार कुछ इस तरह....

public interface IGetLog<T> { } 

    public static class IGetLogExtension 
    { 
    public static ILog GetLogger<T>(this IGetLog<T> getLog) 
    { 
     return LogManager.GetLogger(typeof(T)); 
    } 
    } 
+0

दिलचस्प। ये इतना बुरा नहीं है। मैं इसके बारे में पागल नहीं हूं क्योंकि यह * काफी * सूखा नहीं है, हालांकि यह कम टाइपिंग है, और पुनरावृत्ति एक ही पंक्ति पर है, इसलिए ग़लत वर्ग नाम से गलती से चिपकाया जाने की संभावना कम है। – Ken

+0

सच है, लेकिन एक विशेषता समाधान को याद रखने के लिए प्रत्येक वर्ग पर कोड की रेखा की भी आवश्यकता होती है जिसे आप समर्थन देना चाहते हैं। –

+0

किसी प्रोजेक्ट के प्रत्येक वर्ग को केवल एक निश्चित इंटरफ़ेस को लागू करने के लिए मजबूर करें क्योंकि हम इसमें कुछ लॉग इन नहीं करेंगे, मेरी नाक में खराब गंध आती है। – chiccodoro

1

हमने लॉग 4नेट लपेटा ताकि हम आसानी से इसे बाहर कर सकें। यह ऐसा कुछ है जिसे हम भविष्य में अपने दिमाग को संभवतः बदल सकते हैं।

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

var callingType = new System.Diagnostics.StackTrace().GetFrame(1).GetMethod().DeclaringType 

आप कैसे आप आप केवल उस लागत का कारण बन सकता है जब आप लॉग संदेश की जरूरत है प्रवेश कर रहे हैं के बारे में स्मार्ट रहे हैं।

private static readonly ILog Logger = LogManager.GetLogger(); 

इस विधि इस प्रकार लागू किया गया है:

[MethodImpl(MethodImplOptions.NoInlining)] 
public static ILog GetLogger() 
{ 
    Type t; 
    try { t = new StackFrame(1, false).GetMethod().DeclaringType; } 
    catch { t = typeof(UnknownObject); } 
    return GetLogger(t); 
} 
private static class UnknownObject { } 

यह अभी भी एक दर्द है कि मैं के माध्यम से जाने के लिए तैयार कर रहा हूँ की अधिक साबित होता है

+0

यह प्रोग्राम एक (सुंदर भारी) डेटाबेस के लिए एक फ्रंट एंड है। मैं लगभग सकारात्मक हूं कि किसी भी प्रदर्शन प्रोफ़ाइल पर भी तेजी से डेटाबेस प्रश्नों पर हावी होने जा रहे हैं। :-) – Ken

+0

@ केन आप सबसे खराब मामले पर, प्रत्येक लॉग संदेश के लिए एक स्टैक ट्रेस उत्पन्न करेंगे। आप संभवतः एक वैधानिक कन्स्ट्रक्टर में आरंभ करने के लिए उसी विधि का उपयोग कर सकते हैं जैसा आपने दिखाया था, और प्रति संदेश व्यय से बचें। – Mark

+0

मार्क, आईएमएचओ लॉग 4नेट * वास्तव में एक रैपर से कुछ और नहीं है - लाइब्रेरी में दिए गए एक पूर्वनिर्धारित कार्यान्वयन के आसपास एक रैपर, जिसे आप चाहें अपने आप से बदलना चुन सकते हैं। – chiccodoro

3

हम कुछ लगभग समान का उपयोग करें। मैं लॉगिंग के लिए स्थिर तरीकों के साथ एक स्थिर वस्तु पसंद करते हैं। कॉलिंग विधि प्राप्त करना महंगा नहीं है बशर्ते आपको फ़ाइल जानकारी न मिल जाए। कॉलिंग प्राप्त करने वाले Log4Net को कॉल करने की कीमत की तुलना में कुछ भी नहीं है (इस्तेमाल किए गए लॉगर्स पर कुछ निर्भर करता है)।

+0

दिलचस्प! मैं निश्चित रूप से ऐसा कुछ करने का लुत्फ उठा रहा हूं। – Ken

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