2011-10-21 20 views
16

तो मैं निर्भरता इंजेक्शन का उपयोग करने और इसे करने के लिए आईओसी का उपयोग करने के लिए अपना एएसएमएक्स webservice प्राप्त करने का प्रयास करते समय अटक गया हूं। मैं चाहता हूं कि मेरी webservice मेरी आंतरिक व्यापार परत सेवाओं का उपयोग करने में सक्षम हो। Webservice का उपयोग किसी बाहरी डोमेन से किसी बाहरी डोमेन से किया जाना चाहिए और मुख्य रूप से ऑर्डर और ग्राहकों जैसी संस्थाओं के बारे में जानकारी भेजने और प्राप्त करने के लिए उपयोग किया जाएगा।एएसएमएक्स निर्भरता इंजेक्शन और आईओसी

एक उदाहरण होगा:

public class MyService : System.Web.Services.WebService 
{ 
    [WebMethod] 
    public string HelloWorld() 
    { 
     return new MyBusinessService().MyMethod(); 
    } 
} 

public class MyBusinessService : IMyBusinessService 
{ 
    public string MyMethod() 
    { 
     return "hello"; 
    } 
} 

मैं अपने सेवा को "Newing" की आवश्यकता को समाप्त करने के लिए निर्भरता इंजेक्शन का उपयोग करना चाहते, लेकिन मैं नहीं कर सकते यह करने के लिए एक तरह से यह पता लगाने। मैं इसे गरीब मनुष्य डीआई का उपयोग करके काम करने के लिए प्राप्त कर सकता हूं, या कम से कम मुझे लगता है कि इसे "गरीब मनुष्य" कहा जाता है।

इस तरह:

public class MyService : System.Web.Services.WebService 
{ 
    private IMyBusinessService _myService; 

    public MyService(IMyBusinessService myService) 
    { 
     _myService = myService; 
    } 

    public MyService() : this(new MyBusinessServie()) { } 

    [WebMethod] 
    public string HelloWorld() 
    { 
     return _myService.MyMethod(); 
    } 
} 

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

उत्तर

33

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

एएसपी.नेट के साथ कई रचना जड़ें असामान्य नहीं हैं। जो व्यक्तिगत वेब सेवाओं और वेब पृष्ठों के निर्माता हो सकते हैं। यदि आप एएसपी.नेट एमवीसी का उपयोग कर रहे हैं तो यह कंट्रोलर फैक्ट्री है, जो अधिक डी दोस्ताना है।

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

डी पैटर्न और तकनीकों के संदर्भ में एक अच्छी पुस्तक Dependency Injection in .NET मार्क सेमैन द्वारा संदर्भित है।

यदि आपका वेब सेवा System.Web.IHttpHandler कार्यान्वित बजाय System.Web.Services.WebService से पाने तुम इतनी तरह अपने डि लागू कर सकता है:

Global.ashx.cs

public class Global : HttpApplication 
{ 
    protected void Application_PreRequestHandlerExecute(object sender, EventArgs e) 
    { 
     var context = ((HttpApplication)sender).Context; 

     var needsMyBusinessService = context.Handler as INeedMyBusinessService; 
     if (needsMyBusinessService != null) 
      needsMyBusinessService.MyBusinessService = new MyBusinessService(); 
    } 
} 

MyService.ashx.cs

public class MyService : IHttpHandler, INeedMyBusinessService 
{ 
    public IMyBusinessService MyBusinessService { get; set; } 

    public bool IsReusable { get { return true; } } 

    public void ProcessRequest(HttpContext context) 
    { 
     // uses my dependency 
    } 
} 

INeedMyBusinessService.cs

public interface INeedMyBusinessService 
{ 
    IMyBusinessService MyBusinessService { get; set; } 
} 

हालांकि इस कार्यान्वयन के साथ पकड़ कि है वेब सेवाओं है कि वेब सेवा वस्तु के रूप में System.Web.Services.WebService लागू होने के बाद PreRequestHandlerExecute घटना कॉल जो पिछले घटना है इससे पहले कि ProcessRequest कहा जाता है, आरंभ नहीं किया है के साथ नहीं काम करता है।

उपरोक्त उदाहरण काम करता है यदि आप प्रत्येक वेब सेवा के लिए एक अनूठा उदाहरण चाहते हैं। यदि आप प्रत्येक वेब सेवा अनुरोध के लिए MyBusinessService का एक ही उदाहरण (सिंगलटन लाइफसाइक्ल) रखना चाहते हैं तो आप Global.ashx.cs फ़ाइल को इस तरह कार्यान्वित कर सकते हैं:

public class Global : HttpApplication 
{ 
    private static IMyBusinessService businessService; 

    protected void Application_Start(object sender, EventArgs e) 
    { 
     Global.businessService = new MyBusinessService(); 
    } 

    protected void Application_PreRequestHandlerExecute(object sender, EventArgs e) 
    { 
     var context = ((HttpApplication)sender).Context; 

     var needsMyBusinessService = context.Handler as INeedMyBusinessService; 
     if (needsMyBusinessService != null) 
      needsMyBusinessService.MyBusinessService = Global.businessService; 
    } 
}