दिलचस्प पोस्ट
लिनक्स में एक्लिप्स शुरू करने में त्रुटि: "जेवीएम समाप्त बाहर निकलें कोड = 13 " आईओएस: यूआरएल से छवि डाउनलोड करें और उपकरण में सहेजें रूबी में, 'नया' और 'आरंभ' के बीच संबंध क्या हैं? आरंभ करने के दौरान शून्य कैसे वापस आना है? अजगर में वर्तमान समय कैसे प्राप्त करें? मैं विंडोज पर curl कैसे स्थापित करूं? स्विफ्ट ऑब्जेक्ट में JSON / NSDictionary को डीसरियल करें पीएचपी लघु टैग कैसे सक्षम करें? मैं XSLT के साथ स्ट्रिंग को ऊपरी या निचले-वर्ग में कैसे रूपांतरित कर सकता / सकती हूं? IEnumerable <T> वापसी प्रकार के रूप में गिट वर्कफ़्लो – एक बिल्ड प्रक्रिया सेट करना मतभेदों के लिए दो सूचियों की तुलना करें तत्वों के सेट में एक विशेषता का न्यूनतम मूल्य खोजने के लिए मैं कैसे XPath का उपयोग कर सकता हूं? ES6 के साथ ऑब्जेक्ट विधि / ब्लूबर्ड वादे यह निर्धारित करने के लिए कि क्या ऑब्जेक्ट PySpark में एक मान्य कुंजी-मूल्य जोड़ी है जोरदार टाइप किए गए MVC3 दृश्य से मॉडल पास करने के लिए jquery में AJAX पोस्ट का उपयोग करने का उचित तरीका

विंडसर – कंटेनर से क्षणिक वस्तुओं खींच रहा है

मैं ऑब्जेक्ट को कंटेनर से कैसे खींच सकता हूं जो प्रकृति में क्षणिक है? क्या मुझे उन्हें कंटेनर के साथ पंजीकृत करना होगा और ज़रूरत वर्ग के कन्स्ट्रक्टर को इंजेक्ट करना होगा? कंस्ट्रक्टर में सब कुछ इंजेक्शन करना अच्छा नहीं लगता है इसके अलावा सिर्फ एक वर्ग के लिए मैं TypedFactory बनाने और कारखाने को ज़रूरत वर्ग में इंजेक्ट नहीं करना चाहता।

एक और सोचा था कि मेरे पास आया "नया" उन्हें आवश्यक आधार पर था लेकिन मैं Logger घटक (संपत्ति के माध्यम से) अपने सभी कक्षाओं में भी इंजेक्शन कर रहा हूं इसलिए यदि मैं उन्हें नया बना देता हूं, तो मुझे उन कक्षाओं में Logger मैन्युअल रूप से इन्स्तांत करना होगा। मैं अपने सभी कक्षाओं के लिए कंटेनर का उपयोग कैसे जारी रख सकता हूं?

लकड़हारा इंजेक्शन: मेरी कक्षाओं में से अधिकांश Logger प्रॉपर्टी को परिभाषित करता है, सिवाय इसके कि जहां से विरासत श्रृंखला होती है (उस मामले में केवल आधार वर्ग की यह संपत्ति होती है, और सभी व्युत्पन्न वर्ग इसका इस्तेमाल करते हैं)। जब इन्हें विंडसर कंटेनर के माध्यम से तत्काल ILogger जाता है, तो वे उन में इंजेक्ट किए गए ILogger कार्यान्वयन को प्राप्त करेंगे।

 //Install QueueMonitor as Singleton Container.Register(Component.For<QueueMonitor>().LifestyleSingleton()); //Install DataProcessor as Trnsient Container.Register(Component.For<DataProcessor>().LifestyleTransient()); Container.Register(Component.For<Data>().LifestyleScoped()); public class QueueMonitor { private dataProcessor; public ILogger Logger { get; set; } public void OnDataReceived(Data data) { //pull the dataProcessor from factory dataProcessor.ProcessData(data); } } public class DataProcessor { public ILogger Logger { get; set; } public Record[] ProcessData(Data data) { //Data can have multiple Records //Loop through the data and create new set of Records //Is this the correct way to create new records? //How do I use container here and avoid "new" Record record = new Record(/*using the data */); ... //return a list of Records } } public class Record { public ILogger Logger { get; set; } private _recordNumber; private _recordOwner; public string GetDescription() { Logger.LogDebug("log something"); // return the custom description } } 

प्रशन:

  1. "नया" का उपयोग किए बिना मैं नया Record ऑब्जेक्ट कैसे बना सकता हूं?

  2. QueueMonitor Singleton , जबकि Data "स्कॉप्ड" है। मैं Data को OnDataReceived() विधि में कैसे इंजेक्ट कर सकता हूं?

Solutions Collecting From Web of "विंडसर – कंटेनर से क्षणिक वस्तुओं खींच रहा है"

नमूनों से आप बहुत विशिष्ट हैं, लेकिन सामान्य तौर पर, जब आप कई सेवाओं में ILogger उदाहरण पेश करते हैं, तो आपको अपने आप से दो चीजों से पूछना चाहिए:

  1. क्या मैं बहुत ज्यादा लॉग इन करता हूं?
  2. क्या मैं ठोस सिद्धांतों का उल्लंघन करता हूं?

1. क्या मैं बहुत ज्यादा लॉग इन करता हूं

आप बहुत अधिक लॉगिंग कर रहे हैं, जब आपके पास इस तरह बहुत सारे कोड हैं:

 try { // some operations here. } catch (Exception ex) { this.logger.Log(ex); throw; } 

इस तरह से कोड लिखना त्रुटि की जानकारी खोने की चिंता से आता है। इन सभी प्रकार के प्रयासों को डुप्लिकेट करने के लिए सभी स्थानों पर डुप्लिकेट करना, हालांकि, मदद नहीं करता है इससे भी बदतर, मैं अक्सर डेवलपर्स लॉग इन और जारी देखें (वे अंतिम throw विवरण निकाल throw )। यह वाकई बहुत बुरा है (और पुराने VB ON ERROR RESUME NEXT आगे बढ़ता है), क्योंकि ज्यादातर स्थितियों में यह निर्धारित करने के लिए पर्याप्त जानकारी नहीं है कि यह सुरक्षित है या नहीं। अक्सर कोड में एक बग है जिसके कारण ऑपरेशन विफल हो गया था। जारी रखने के लिए इसका मतलब है कि उपयोगकर्ता अक्सर यह विचार प्राप्त करता है कि ऑपरेशन सफल रहा, जबकि यह नहीं है। अपने आप से पूछिए: क्या बुरा है, उपयोगकर्ता को एक सामान्य त्रुटि संदेश दिखा रहा है कि कुछ गलत हो गया है, या चुपचाप त्रुटि को छोड़कर और उपयोगकर्ता को लगता है कि उसका अनुरोध सफलतापूर्वक संसाधित हो गया है? इस बारे में सोचें कि उपयोगकर्ता को दो हफ्ते बाद पता चला कि उसका ऑर्डर कभी भी नहीं भेजा गया था, तो उपयोगकर्ता कैसे महसूस करेगा। शायद आप ग्राहक खो देंगे या इससे भी बदतर, एक मरीज का एमआरएसए पंजीकरण चुपचाप विफल हो जाता है, जिसके कारण मरीज को नर्सिंग द्वारा अलग-थलग नहीं किया जाता है और जिसके परिणामस्वरूप अन्य रोगियों के दूषित होने के कारण उच्च लागत या शायद मौत भी हो सकती है।

इन प्रकार के अधिकांश प्रयास-पकड़-लॉग लाइनों को हटा दिया जाना चाहिए और आपको कॉल स्टैक को अपवाद बुलबुला देना चाहिए।

आप लॉग इन नहीं करना चाहिए? आप बिल्कुल चाहिए! लेकिन यदि आप कर सकते हैं, आवेदन के शीर्ष पर एक प्रयास-पकड़ ब्लॉक को परिभाषित करें। ASP.NET के साथ, आप Application_Error इवेंट को लागू कर सकते हैं, एक HttpModule पंजीकृत करें या एक कस्टम त्रुटि पृष्ठ को परिभाषित कर सकते हैं जो लॉगिंग करता है विन फॉर्म के साथ समाधान भिन्न होता है, लेकिन अवधारणा एक ही रहता है: एक एकल शीर्ष सबसे अधिक कैच-सब को परिभाषित करें

कभी-कभी हालांकि, आप अभी भी एक निश्चित प्रकार के अपवाद को पकड़ना और लॉग इन करना चाहते हैं। एक प्रणाली जिस पर मैंने पहले काम किया था, व्यापार स्तर को ValidationException दिया, जो प्रस्तुति स्तर से पकड़ा जाएगा। उन अपवादों में उपयोगकर्ता के प्रदर्शन के लिए सत्यापन जानकारी होती है। चूंकि उन अपवादों को प्रस्तुतीकरण परत में पकड़े और संसाधित किया जाता है, इसलिए वे आवेदन के शीर्ष सबसे ऊपर तक बुलबुला नहीं करते थे और एप्लिकेशन के कैच-कोड में समाप्त नहीं हुए थे। फिर भी मैं इस जानकारी को लॉग इन करना चाहता हूं, यह जानने के लिए कि उपयोगकर्ता ने कितनी बार अमान्य जानकारी दर्ज की है और यह पता लगाने के लिए कि सही कारणों से कहां से आने वाले सत्यापन। तो यह कोई त्रुटि लॉगिंग नहीं था; बस लॉगिंग मैंने ऐसा करने के लिए निम्नलिखित कोड लिखा था:

 try { // some operations here. } catch (ValidationException ex) { this.logger.Log(ex); throw; } 

जाना पहचाना? हां, पिछले कोड स्निपेट के समान ही दिखता है, इस अंतर के साथ कि मैंने केवल ValidationException पकड़ लिया हालांकि, एक और अंतर था, जो सिर्फ स्निपेट को देखकर नहीं देखा जा सकता है। उस कोड में निहित आवेदन में केवल एक स्थान था! यह एक डेकोरेटर था, जिसने मुझे अगले प्रश्न के लिए लाया जो आपको खुद से पूछना चाहिए:

2. क्या मैं ठोस सिद्धांतों का उल्लंघन करता हूं?

लॉगिंग, ऑडिटिंग और सुरक्षा जैसी चीजों को क्रॉस-कटिंग चिंताओं (या पहलुओं) कहा जाता है उन्हें क्रॉस-कटिंग कहा जाता है, क्योंकि वे आपके आवेदन के कई परतों में कटौती कर सकते हैं और उन्हें सिस्टम में कई कक्षाओं पर अक्सर लागू किया जा सकता है। हालांकि, जब आप पाते हैं कि आप सिस्टम में कई वर्गों में उपयोग के लिए कोड लिख रहे हैं, तो आप सबसे अधिक संभावना SOLID सिद्धांतों का उल्लंघन कर रहे हैं उदाहरण के लिए निम्नलिखित उदाहरण लें:

 public void MoveCustomer(int customerId, Address newAddress) { var watch = Stopwatch.StartNew(); // Real operation this.logger.Log("MoveCustomer executed in " + watch.ElapsedMiliseconds + " ms."); } 

यहाँ हम MoveCustomer ऑपरेशन को निष्पादित करने के लिए लेते समय का आकलन करते हैं और हम उस जानकारी को लॉग इन करते हैं। यह बहुत संभावना है कि सिस्टम में अन्य परिचालनों को इस समान क्रॉस-कटिंग चिंता की आवश्यकता है। आप अपने ShipOrder , CancelOrder , CancelShipping आदि के लिए इस तरह से कोड जोड़ना शुरू कर देंगे। इस तरीके से बहुत सारे कोड दोहराव होते हैं और अंत में एक रखरखाव दुःस्वप्न होता है।

यहां समस्या ठोस सिद्धांतों का उल्लंघन है ठोस सिद्धांत ऑब्जेक्ट ओरिएंटेड डिज़ाइन सिद्धांतों का एक सेट हैं जो लचीला और रखरखाव सॉफ्टवेयर को परिभाषित करने में आपकी सहायता करते हैं। MoveCustomer उदाहरण में कम से कम दो नियमों का उल्लंघन किया गया है:

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

ठोस सिद्धांतों का उल्लंघन करने के अलावा हम निश्चित रूप से ड्रिल सिद्धांत का उल्लंघन करते हैं, जो मूल रूप से कहता है कि कोड दोहराव खराब है, मैके।

इस समस्या का हल लॉगिंग को अपने वर्ग में निकालने और उस वर्ग को मूल वर्ग को लपेटने की अनुमति देता है:

 // The real thing public class MoveCustomerCommand { public virtual void MoveCustomer(int customerId, Address newAddress) { // Real operation } } // The decorator public class MeasuringMoveCustomerCommandDecorator : MoveCustomerCommand { private readonly MoveCustomerCommand decorated; private readonly ILogger logger; public MeasuringMoveCustomerCommandDecorator( MoveCustomerCommand decorated, ILogger logger) { this.decorated = decorated; this.logger = logger; } public override void MoveCustomer(int customerId, Address newAddress) { var watch = Stopwatch.StartNew(); this.decorated.MoveCustomer(customerId, newAddress); this.logger.Log("MoveCustomer executed in " + watch.ElapsedMiliseconds + " ms."); } } 

असली उदाहरण के आसपास डेकोरेटर को लपेटकर, आप इस मापने के व्यवहार को कक्षा में बदल सकते हैं, बिना किसी दूसरे हिस्से को बदलने के लिए:

 MoveCustomerCommand command = new MeasuringMoveCustomerCommandDecorator( new MoveCustomerCommand(), new DatabaseLogger()); 

पिछले उदाहरण में हालांकि समस्या का एक हिस्सा अभी हल किया (केवल ठोस भाग)। ऊपर दिखाए गए कोड को लिखते समय, आपको सिस्टम में सभी कार्यों के लिए सज्जाकार को परिभाषित करना होगा, और आप मीज़ुरिंगशिप ऑर्डर कॉमांड MeasuringShipOrderCommandDecorator , MeasuringCancelOrderCommandDecorator ऑर्डर कॉमांड डिक्टोरेटर और MeasuringCancelShippingCommandDecorator एसपिंग कॉमांड डिक्टोरेटर जैसी MeasuringShipOrderCommandDecorator साथ समाप्त होंगे। यह कई डुप्लिकेट कोड (ड्रिल सिद्धांत का उल्लंघन) करने के लिए फिर से नेतृत्व करता है, और सिस्टम में हर संचालन के लिए अभी भी कोड लिखने की आवश्यकता है। यहां क्या गुम है सिस्टम में उपयोग के मामलों पर एक आम अमूर्त है। जो गुम है वह एक ICommandHandler<TCommand> इंटरफ़ेस है ICommandHandler<TCommand>

इस अंतरफलक को परिभाषित करें:

 public interface ICommandHandler<TCommand> { void Execute(TCommand command); } 

और चलो MoveCustomer विधि के विधि तर्क अपने खुद के ( पैरामीटर ऑब्जेक्ट ) वर्ग MoveCustomerCommand बुलाया में MoveCustomerCommand :

 public class MoveCustomerCommand { public int CustomerId { get; set; } public Address NewAddress { get; set; } } 

और हम एक क्लास में MoveCustomer विधि का व्यवहार करते हैं जो MoveCustomer ICommandHandler<MoveCustomerCommand> लागू करता है:

 public class MoveCustomerCommandHandler : ICommandHandler<MoveCustomerCommand> { public void Execute(MoveCustomerCommand command) { int customerId = command.CustomerId; var newAddress = command.NewAddress; // Real operation } } 

यह अजीब लग सकता है, लेकिन क्योंकि अब हमारे पास उपयोग मामलों के लिए एक सामान्य अमूर्त है, हम अपने डेकोरेटर को निम्न प्रकार से लिख सकते हैं:

 public class MeasuringCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand> { private ICommandHandler<TCommand> decorated; private ILogger logger; public MeasuringCommandHandlerDecorator( ICommandHandler<TCommand> decorated, ILogger logger) { this.decorated = decorated; this.logger = logger; } public void Execute(TCommand command) { var watch = Stopwatch.StartNew(); this.decorated.Execute(command); this.logger.Log(typeof(TCommand).Name + " executed in " + watch.ElapsedMiliseconds + " ms."); } } 

यह नया MeasuringCommandHandlerDecorator<T> मेसुरिंगमव कस्टमर कॉमांड डिक्कोरेटर की तरह दिखता है, लेकिन इस क्लास को सिस्टम में सभी कमांड हैंडलरों के लिए पुन: उपयोग किया जा सकता है:

 ICommandHandler<MoveCustomerCommand> handler1 = new MeasuringCommandHandlerDecorator<MoveCustomerCommand>( new MoveCustomerCommandHandler(), new DatabaseLogger()); ICommandHandler<ShipOrderCommand> handler2 = new MeasuringCommandHandlerDecorator<ShipOrderCommand>( new ShipOrderCommandHandler(), new DatabaseLogger()); 

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

 ICommandHandler<MoveCustomerCommand> handler1 = Decorate(new MoveCustomerCommandHandler()); ICommandHandler<ShipOrderCommand> handler2 = Decorate(new ShipOrderCommandHandler()); private static ICommandHandler<T> Decorate<T>(ICommandHandler<T> decoratee) { return new MeasuringCommandHandlerDecorator<T>( new DatabaseLogger(), new ValidationCommandHandlerDecorator<T>( new ValidationProvider(), new AuthorizationCommandHandlerDecorator<T>( new AuthorizationChecker( new AspNetUserProvider()), new TransactionCommandHandlerDecorator<T>( decoratee)))); } 

यदि आपका आवेदन बढ़ने शुरू होता है, तो यह कंटेनर के बिना यह सब बूटस्ट्रैप के लिए दर्दनाक हो सकता है। खासकर जब आपके सज्जाकारों को सामान्य प्रकार की बाधाएं हैं

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

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

इस अनुच्छेद को पढ़ें यदि आप अपने आवेदन को डिजाइन करने के इस तरीके के बारे में अधिक जानना चाहते हैं: इस बीच … मेरे आर्किटेक्चर के कमांड पक्ष पर ।

आशा है कि ये आपकी मदद करेगा।