2010-04-29 12 views
5

के साथ सेवा लोकेटर से बचें मैं एक एप्लिकेशन बना रहा हूं जो DI के लिए ऑटोफ़ैक 2 का उपयोग करता है। मैं reading रहा हूं कि एक स्थिर IoCHelper (सेवा लोकेटर) का उपयोग करना चाहिए।ऑटोफ़ैक 2

IoCHelper.cs

public static class IoCHelper 
{ 
    private static AutofacDependencyResolver _resolver; 

    public static void InitializeWith(AutofacDependencyResolver resolver) 
    { 
     _resolver = resolver; 
    } 

    public static T Resolve<T>() 
    { 
     return _resolver.Resolve<T>(); 
    } 
} 

एक previous question के जवाब से, मैं एक तरह से मदद करने के लिए Auto-generated Factories के उपयोग के माध्यम से मेरे UnitOfWork में मेरी IoCHelper उपयोग करने के लिए की जरूरत को कम पाया गया। इस पथ को जारी रखते हुए, मैं उत्सुक हूं अगर मैं पूरी तरह से अपने IoCHelper को खत्म कर सकता हूं। मैं एक स्थिर सेटिंग वर्ग है कि मेरे विन्यास कार्यान्वयन के चारों ओर एक आवरण के रूप में कार्य करता है है

:

यहाँ परिदृश्य है। चूंकि सेटिंग क्लास मेरी अन्य कक्षाओं के बहुमत की निर्भरता है, इसलिए रैपर मुझे अपने आवेदन के दौरान सेटिंग कक्षा को इंजेक्ट करने से रोकता है।

Settings.cs

public static class Settings 
{ 
    public static IAppSettings AppSettings 
    { 
     get 
     { 
      return IoCHelper.Resolve<IAppSettings>(); 
     } 
    } 
} 

public interface IAppSettings 
{ 
    string Setting1 { get; } 
    string Setting2 { get; } 
} 

public class AppSettings : IAppSettings 
{ 
    public string Setting1 
    { 
     get 
     { 
      return GetSettings().AppSettings["setting1"]; 
     } 
    } 

    public string Setting2 
    { 
     get 
     { 
      return GetSettings().AppSettings["setting2"]; 
     } 
    } 

    protected static IConfigurationSettings GetSettings() 
    { 
     return IoCHelper.Resolve<IConfigurationSettings>(); 
    } 
} 

वहाँ एक रास्ता एक सेवा लोकेटर का उपयोग किए बिना और प्रत्येक और हर वर्ग में AppSettings इंजेक्शन का सहारा के बिना इस संभाल करने के लिए है? नीचे सूचीबद्ध 3 जिन क्षेत्रों में मैं निर्माता इंजेक्शन के बजाय ServiceLocator पर झुकाव रखने हैं:

  • AppSettings
  • लॉगिंग
  • कैशिंग

उत्तर

4

मैं नहीं बल्कि हर वर्ग इसकी आवश्यकता है कि में IAppSettings डालेगी उन्हें Settings पर छिपी निर्भरता से साफ रखने के लिए। प्रश्न यह है कि, क्या आपको वास्तव में उस वर्ग पर निर्भरता को छिड़कने की ज़रूरत है?

यदि आप वास्तव में एक स्थिर Settings कक्षा के साथ जाना चाहते हैं तो मैं कम से कम परीक्षण-अनुकूल/नकली बनाने की कोशिश करता हूं। इस पर विचार करें:

public static class Settings 
{ 
    public static Func<IAppSettings> AppSettings { get; set; } 
} 

और जहां आप अपने कंटेनर का निर्माण:

var builder = new ContainerBuilder(); 
... 
var container = builder.Build(); 

Settings.AppSettings =() => container.Resolve<IAppSettings>(); 

इस परीक्षण के दौरान नकली के साथ बाहर स्वैप करने की अनुमति होगी:

Settings.AppSettings =() => new Mock<IAppSettings>().Object; 

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

public class AppSettings : IAppSettings 
{ 
    private readonly Func<IConfigurationSettings> _configurationSettings; 

    public AppSettings(Func<IConfigurationSettings> configurationSettings) 
    { 
     _configurationSettings = configurationSettings; 
    } 

    public string Setting1 
    { 
     get 
     { 
      return _configurationSettings().AppSettings["setting1"]; 
     } 
    } 

    public string Setting2 
    { 
     get 
     { 
      return _configurationSettings().AppSettings["setting2"]; 
     } 
    } 
} 
+0

यह एक अच्छा मुद्दा है। सचमुच, मुझे शायद उन निर्भरताओं को हर वर्ग में इंजेक्ट करने की आवश्यकता नहीं है, लेकिन उन मामलों के लिए जब मेरे पास समान निर्भरता को बड़ी संख्या में कक्षाओं में इंजेक्शन दिया जाता है, तो मैं केवल उत्सुक था कि इसके लिए कुछ डीआई सर्वोत्तम अभ्यास है। –

+1

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

+0

अच्छा कामकाज – Baldy

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