2013-01-02 24 views
17

मैं वर्तमान में एक प्रोजेक्ट पर काम कर रहा हूं जहां हम अपनी पुरानी डेटासेट, संग्रहीत प्रक्रिया WinForm एप्लिकेशन को एंटीटी फ्रेमवर्क का उपयोग करने के लिए परिवर्तित कर रहे हैं, इसलिए नई वेबसाइटें उसी ऑब्जेक्ट मॉडल और रिपॉजिटरीज़ तक पहुंच सकती हैं।निनजेक्ट और एंटिटी फ्रेमवर्क का उपयोग कर WinForms में निर्भरता इंजेक्शन

वैसे भी, मैं फॉर्म में निर्भरता इंजेक्शन को लागू करने की कोशिश कर रहा हूं ताकि हम इकाई परीक्षण के लिए नकली रेपॉजिटरीज़ का उपयोग कर सकें। मैं एमवीसी वेबसाइटों में पहले इस्तेमाल किए गए साधारण कारण के लिए निनजेक्ट का उपयोग कर रहा हूं, हालांकि WinForm एप्लिकेशन में इसे लागू करने की कोशिश करना कम से कम कहने में समस्याग्रस्त साबित हो रहा है, WinForms में DI पर जानकारी की कमी से और भी बाधित मकड़जाल।

अब तक मैंने निनजेक्ट फैक्ट्री और रिपोजिटरी बनाई हैं, लेकिन मुझे भंडारों को रूपों में इंजेक्शन देने में बहुत भाग्य नहीं है।

इसलिए कोई मेरी मदद कर सकता है या कोई सुझाव दे सकता है?

नीचे मैं अपने कोड के कुछ हिस्सों कि मदद कर सकता है है:

Ninject फैक्टरी: खजाने के साथ

public class NinjectFactory : NinjectModule 
{ 
    private IKernel _ninjectKernel; 

    public NinjectFactory() 
    { 
     _ninjectKernel = new StandardKernel(); 
    } 

    public override void Load() 
    { 
     _ninjectKernel.Bind(typeof(IRepository<>)).To(typeof(GenericRepository<>)); 
     _ninjectKernel.Bind(typeof(IProductionRepository)).To(typeof(ProductionRepository)); 
    } 
} 

प्रपत्र:

Public Class TaskForm 
    Inherits BaseBusinessDialogForm 

    Private _repository As TaskRepository 
    Private _task As Production.Task = Nothing 

    Public Sub New(ByVal task As Production.Task) 

     InitializeComponent() 

     _repository = New TaskRepository(ConnectString) 

     If task.TaskID = 0 Then 
      _task = task 
     Else 
      _task = _repository.GetByID(task.TaskID) 
     End If 

     MyBase.BusinessObject = _task 
     Me.TaskBindingSource.DataSource = MyBase.BusinessObject 

    End Sub 

क्लास कि एमडीआई रूप है जो ऊपर रखती है की शुरूआत फॉर्म:

Dim kernel As IKernel = New StandardKernel(New NinjectFactory()) 
''Dim kernel As IKernel = New StandardKernel(New NinjectFactoryTest()) 
mfrmMDI = kernel.Get(Of Forms.MDI)() 

Application.DoEvents() 
mfrmMDI.ShowDialog() 

मैं समझता हूं कि मेरा प्रश्न थोड़ा अस्पष्ट है, लेकिन मुझे यकीन नहीं है कि समस्या कहां है या मुझे क्या पूरा करने की आवश्यकता है।

धन्यवाद बहुत बहुत

+0

आप की वीबी और सी # जुली एक संलग्न प्रकार पता चलता है, होगा सी # पर पूरी तरह उत्तर देना ठीक है? –

+0

भाषाओं के मिश्रण के लिए खेद है, यह सीधे परियोजना कोड से है। पुरानी चीजें वीबी में हैं और सी # में नई है, कम से कम कहने के लिए परेशान! – XN16

उत्तर

31

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

public class CompositionRoot 
{ 
    private static IKernel _ninjectKernel; 

    public static void Wire(INinjectModule module) 
    { 
     _ninjectKernel = new StandardKernel(module); 
    } 

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

आपका मॉड्यूल इस

public class ApplicationModule : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind(typeof(IRepository<>)).To(typeof(GenericRepository<>)); 
    } 
} 

मुख्य विधि में की तरह लग रही आप एक पैरामीटर के रूप ApplicationModule गुजरती हैं और Form1 को हल करने और इसे शुरू होगा।

[STAThread] 
static void Main() 
{ 
    CompositionRoot.Wire(new ApplicationModule()); 

    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 

    Application.Run(CompositionRoot.Resolve<Form1>()); 
} 

Form1 निर्माता में आप आवश्यक भंडार विशिष्ट साथ सामान्य मापदंडों

बंद कर दिया पारित
public partial class Form1 : Form 
{ 
    private IRepository<Process> _processRepository; 

    public Form1(IRepository<Process> productionRepository) 
    { 
     this._processRepository = productionRepository;   
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     MessageBox.Show(_processRepository.ToString()); 
    } 
} 

आपका खजाने बहुत जटिल हो सकता है, लेकिन मैं इतना है कि ToString() विधि के बजाय उन्हें किसी भी कार्यक्षमता शामिल नहीं करेंगे, हम देख सकते थे कि निर्भरता सही तरीके से हल की गई थी या नहीं। ध्यान दें कि भंडारों पर कोई भी विशेषता नहीं है।

public interface IRepository<T> 
{ 
} 

public class GenericRepository<T> : IRepository<T> 
{ 
    public override string ToString() 
    { 
     return "MyRepository with type : "+typeof(T).Name; 
    } 
} 

अब जब आप अपने एप्लिकेशन को चलाने के लिए, आप देखेंगे कि सब तार किया है और संदेश बॉक्स के रूप में Process

enter image description here

+0

बहुत बहुत धन्यवाद, मैंने आपके उदाहरण का एक संस्करण सफलतापूर्वक कार्यान्वित करने में कामयाब रहा है। – XN16

+2

मुझे लगता है कि आप एक रचना रूट का इरादा करने का इरादा खो रहे हैं। आपका "रचना रूट" वास्तव में एक सेवा लोकेटर है, जिसे अक्सर एक एंटीपाटर माना जाता है। एक वास्तविक संरचना रूट आपके चल रहे एप्लिकेशन के ऑब्जेक्ट ग्राफ़ में "शीर्ष स्तर" ऑब्जेक्ट है, और यह एकमात्र ऑब्जेक्ट होना चाहिए जिसे आप स्पष्ट रूप से कर्नेल (कारखानों को छोड़कर) से पूछते हैं। जड़ का निर्माण होने पर या कारखाने के माध्यम से तत्काल के माध्यम से इंजेक्शन के माध्यम से बाकी सब कुछ हल किया जाना चाहिए। – FMM

+0

मेरा 'कंपोज़िशन रूट' एक सेवा लोकेटर नहीं है। 'फॉर्म 1' 'आईआरपीओसेटरी ' कन्स्ट्रक्टर तर्क के रूप में पूछें, न कि 'कंपोज़िशन रूट'। 'कंपोज़िशन रूट' एप्लिकेशन की शुरुआत में ** पूर्ण ** ऑब्जेक्ट ग्राफ़ को हल करता है। आप कर्नेल से 'कंपोज़िशन रूट' नहीं पूछते हैं, बल्कि इसके बजाय आप 'कंपोज़िशन रूट' से शीर्ष ऑब्जेक्ट्स से पूछते हैं और यह आपके लिए एक पूर्ण हल ऑब्जेक्ट ग्राफ़ प्रदान करता है। –