7

बनाए रख सकते हैं मैं स्विच बयान से बचना चाहते थे आईओसी के साथ एक स्विच बयान की जगह है। मेरे पास 30 से अधिक दस्तावेज़ प्रकार हैं। एक संभावना भी है कि मुझे आगे बढ़ने वाले अधिक दस्तावेज़ प्रकार जोड़ने की आवश्यकता होगी। मैं आईडी दस्तावेज़ पास कर दूंगा और आईडी दस्तावेज़ के कार्यान्वयन में निर्दिष्ट प्रकार होगा। कुछ और मैं उल्लेख करना भूल गया ProgressNoteViewModel, LabViewModel ... सभी WorkspaceViewModel से विरासत और ठोस कार्यान्वयन कंस्ट्रक्टर्स के सभी पैरामीटर के रूप में एक प्रकार IPatient ले गया था। मैं अपने आईओसी कंटेनर के रूप में कैसल का उपयोग कर रहामैं कैसे तो मैं ठोस सिद्धांत

मैं की तरह

viewModel = new TreeViewModel(repository.GetPatientDocumentListing(IDocumentType); 
this.DocTreeViewModel = viewModel; 
//How would I then be able to instantiate the right ViewModel 
//based on IDocumentType and also pass a object into the 
//constructor that is not know at compile time 

मैं निम्नलिखित कोड है कुछ करने के लिए कोड refactor करने के लिए चाहते हो जाएगा:

switch (docType) 
{ 
    case "ProgressNotes": 
     viewModel = new TreeViewModel(repository.GetPatientProgressNotes()); 
     this.DocTreeViewModel = viewModel; 
     ProgressNoteViewModel workspace = ProgressNoteViewModel.NewProgressNoteViewModel(_patient); 
     break; 
    case "Labs": 
     viewModel = new TreeViewModel(repository.GetPatientLabs()); 
     this.DocTreeViewModel = viewModel; 
     LabViewModel workspace = LabViewModel.NewLabViewModel(_patient); 
     break; 
} 
this.Workspaces.Add(workspace); 
this.SetActiveWorkspace(workspace); 
+0

क्या आईओसी कंटेनर का उपयोग कर रहे:

class ViewModelBuilderFactory { private Dictionary<string, System.Type> resolver; public void ViewModelBuilderFactory() { resolver = new Dictionary<string, Type> { {"ProgressNotes", typeof(ProgressNotesViewModelBuilder)}, {"Labs", typeof(LabsViewModelBuilder)} }; } public IViewModelBuilder GetViewModelBuilder(string key) { System.Type type = this.resolver[key]; return (IViewModelBuilder)Activator.CreateInstance(type); } } 

संपादित

कैसल विंडसर का उपयोग करके उपरोक्त जवाब की चर्चा करते हुए निम्न कोड नामित घटकों लेकिन कोड में प्रारंभ का उपयोग कर एक ही कर सकता है? – smaclell

उत्तर

4

पूरी तरह से अपरीक्षित:

public class ViewModelBuilderFactory 
{ 
    public IViewModelBuilder GetViewModelBuilder (string docType, IRepository repository) 
    { 
     switch (docType) 
     { 
      case "ProgressNotes": 
       return new ProgressNotesViewModelBuilder(repository); 
      case "Labs": 
       return new LabsViewModelBuilder(repository); 
      default: 
       throw new ArgumentException(
        string.Format("docType \"{0}\" Invalid", docType); 
     } 
    } 
} 

public interface IViewModelBuilder 
{ 
    TreeViewModel GetDocTreeViewModel(); 
    WorkSpace GetWorkSpace(Patient patient); 
} 

public class LabsViewModelBuilder : IViewModelBuilder 
{ 
    private IRepository _repository; 
    public LabsViewModelBuilder(IRepository repository) 
    { 
     _repository = repository; 
    } 

    public TreeViewModel GetDocTreeViewModel() 
    { 
     return new TreeViewModel(_repository.GetPatientLabs()); 
    } 

    public Workspace GetWorkspace(Patient patient) 
    { 
     return LabViewModel.NewLabViewModel(patient); 
    } 
} 

public class ProgressNotesViewModelBuilder : IViewModelBuilder 
{ 
    private IRepository _repository; 
    public ProgressNotesViewModelBuilder(IRepository repository) 
    { 
     _repository = repository; 
    } 

    public TreeViewModel GetDocTreeViewModel() 
    { 
     return new TreeViewModel(_repository.GetPatientProgressNotes()); 
    } 

    public Workspace GetWorkspace(Patient patient) 
    { 
     return ProgressNoteViewModel.NewProgressNoteViewModel(patient); 
    } 
} 

अब आप अपने फोन करने कोड है:

ViewModelBuilderFactory factory = new ViewModelBuilderFactory(); 
IViewModelBuilder modelBuilder = factory.GetViewModelBuilder(docType, repository); 
this.DocTreeViewModel = modelBuilder.GetDocTreeViewModel(); 
Workspace workspace = modelBuilder.GetWorkspace(patient); 
this.Workspaces.Add(workspace); 
this.SetActiveWorkspace(workspace); 

[4 संपादन पहली पोस्ट के बाद से; गलतियों]

[आगे संपादित करें यह देखते हुए कि आप उपयोग कर रहे कैसल आईओसी]

अपने महल एक्सएमएल विन्यास में, आप जोड़ सकते दिखाई दे रहा है (और मैं यहाँ कैसल के केवल एक अस्पष्ट ज्ञान पर काम कर रहा हूँ)

<component id="ProgressNotesViewModelBuilder" 
      type="MyNamespace.ProgressNotesViewModelBuilder, MyAssembly"> 
    <parameters> 
     <!-- reference to repository here --> 
    </parameters> 
</component> 
<component id="LabsViewModelBuilder" 
      type="MyNamespace.LabsViewModelBuilder, MyAssembly"> 
    <parameters> 
     <!-- reference to repository here --> 
    </parameters> 
</component> 

तो फिर तुम ViewModelBuilderFactory की जरूरत नहीं है, तो आप सिर्फ

के साथ

IViewModelBuilder modelBuilder = factory.GetViewModelBuilder(docType, repository); 

जगह ले सकता है

IViewModelBuilder modelBuilder = (IViewModelBuilder) 
    container.Resolve(docType + "ViewModelBuilder"); 

अब आप सब पर अपने स्विच बयान की जरूरत नहीं है।

हालांकि, यह ध्यान देने योग्य है कि स्विच बुरा नहीं हैं, वे सिर्फ खराब गंध करते हैं और सभी बुरी गंधों को अच्छी तरह से गंध की तरह से अलग किया जाना चाहिए; कारखाने के पैटर्न को हासिल करने का इरादा यही है।

+0

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

+0

उन्हें इंटरफेस को लागू करने का मतलब है, यह अन्यथा कोई समझ नहीं आता है। संपादित। – pdr

+0

नियंत्रण सिद्धांत के विचलन के साथ फिट करने के लिए परिवर्तन कंक्रीट कार्यान्वयन 'प्रोग्रेस नोट्स व्यू मॉडेल बिल्डर' या 'लैब्स व्यू मॉडेलबिल्डर' के बजाय 'IViewModelbuilder' पर निर्भर है। – smaclell

1

आईओसी कंटेनर के बजाय मैं रणनीति और कारखाने पैटर्न गठबंधन करने के लिए कोशिश करेंगे। यदि आपको प्रत्येक मामले के लिए कस्टम कन्स्ट्रक्टर पैरामीटर की आवश्यकता है, तो मुझे लगता है कि आपको वायरिंग के साथ उचित आईओसी कंटेनर चाहिए।

container.Register(Component 
.For<IViewModelBuilder>() 
.ImplementedBy<ProgressNotesViewModelBuilder>() 
.Named("ProgressNotes")); 
container.Register(Component 
.For<IViewModelBuilder>() 
.ImplementedBy<LabsViewModelBuilder>() 
.Named("Labs")); 

var builder = container.Resolve<IViewModelBuilder>(key);