2011-11-29 10 views
5

के लिए अलग हैं मैं एक फ़िल्टर/पाइपलाइन पैटर्न लागू करने के लिए इतना है कि मैं एक इनपुट, यह प्रक्रिया फिल्टर के एक नंबर के माध्यम से लेते हैं और अंत में एक उत्पादन प्राप्त कर सकते हैं कोशिश कर रहा हूँ।जेनेरिक पाइपलाइन जहां इनपुट/आउटपुट प्रकार प्रत्येक फिल्टर

मैं आसानी से कर सकते जब इनपुट प्रकार और अंतिम आउटपुट प्रकार एक ही कर रहे हैं और प्रत्येक फिल्टर एक ही प्रकार भी उपयोग करता है। हालांकि, मैं एक प्रकार इनपुट करना चाहता हूं और एक और प्रकार प्राप्त करना चाहता हूं।

उदा। उसके फ़ाइलनाम से एक csvfile ले लो, अलग-अलग स्ट्रिंग में इसे लोड, उन्हें पार्स, मान्य व एक्सएमएल के रूप में उत्पादन। छद्म कोड उदाहरण:

IFilter, FilterBase, FilterImplementation 
IPipeline, Pipeline 
IBusinessObject, BusinessObject, BusinessObjectImplementation 

मेरे इरादे IFilter<T,U> की एक सूची के लिए जहां T and U are IBusinessObject

हालांकि, मैं एक मिल "सक्षम होने के लिए किया गया था:

input = filename 
filter = load csv file <filename, list<string>> 
filter = parse csv <list<string>, list<businessobject>> 
filter = validate objects <list<businessobject>, list<businessobject>> *... return type same as input type in this case.* 
filter = create xml <list<businessobject>, XDocument> 
filter = validate XDoc <XDocument, XDocument> 
output = XDocument 

यहाँ मैं अब तक किया है जब सूची में एक IFilter<IBusinessObject, IBusinessObject> जोड़ने की कोशिश कर "BusinessObjectImplementation से IBusinessObject को परिवर्तित नहीं कर सकते। सभी कोड के लिए

Apols ... अपने आखिरी बात यह है कि


public interface IFilter<T, U> 
     where T : IBusinessObject 
     where U : IBusinessObject 
    { 
     U Execute(T input); 
    } 

    public abstract class FilterBase<T, U> : IFilter<T, U> 
     where T : IBusinessObject 
     where U : IBusinessObject, new() 
    { 
     protected abstract U Process(T input); 

     public U Execute(T input) 
     { 
      return Process(input); 
     } 

    } 

    public class FilterCsvFileLoader<T, U> : FilterBase<T, U>, IFilter<T, U> 
     where T : FilenameObject, IBusinessObject 
     where U : CSVFile, IBusinessObject, new() 
    { 
     public FilterCsvFileLoader() 
     { } 

     protected override U Process(T input) 
     { 
      U result = new CSVFile(input) as U; 
      return result; 
     } 
    } 

public interface IPipeline 
    { 
     IBusinessObject Execute(IBusinessObject input); 

     IPipeline Register(IFilter<IBusinessObject, IBusinessObject> filter); 
    } 

    public class Pipeline : IPipeline 
    { 
     private List<IFilter<IBusinessObject, IBusinessObject>> _filters = new List<IFilter<IBusinessObject, IBusinessObject>>(); 

     public IBusinessObject Execute(IBusinessObject input) 
     { 
      var result = input; 
      foreach (var filter in _filters) 
      { 
       result = filter.Execute(result); 
      } 
      return result; 
     } 

     public IPipeline Register(IFilter<IBusinessObject, IBusinessObject> filter) 
     { 
      _filters.Add(filter); 
      return this; 
     } 
    } 

public interface IBusinessObject 
    { 
     bool Validate(); 
     List<string> ValidationErrors { get; } 
    } 

    public class BusinessObject : IBusinessObject 
    { 
     private List<BusinessRule> _businessRules = new List<BusinessRule>(); 

     private List<string> _validationErrors = new List<string>(); 

     public List<string> ValidationErrors 
     { 
      get { return _validationErrors; } 
     } 
     protected void AddRule(BusinessRule rule) 
     { 
      _businessRules.Add(rule); 
     } 

     public bool Validate() 
     { 
      bool isValid = true; 

      _validationErrors.Clear(); 

      foreach (BusinessRule rule in _businessRules) 
      { 
       if (!rule.Validate(this)) 
       { 
        isValid = false; 
        _validationErrors.Add(rule.ErrorMessage); 
       } 
      } 
      return isValid; 
     } 
    } 

    public class FilenameObject : BusinessObject, IBusinessObject 
    { 
     string _filename; 

     public string Filename 
     { 
      get { return _filename; } 
     } 

     public FilenameObject(string filename) 
     { 
      _filename = filename; 
     } 
    } 

    public class CSVFile : BusinessObject, IBusinessObject 
    { 
     private string _filename; 
     private string[] _splitChar = new string[] { "," }; 

     public List<List<string>> Lines { get; set; } 

     public CSVFile() 
     { } 

     public CSVFile(FilenameObject filename) 
      : this() 
     { 
      _filename = filename.Filename; 
      Lines = new List<List<string>>(); 
     } 

     private void ImportFile() 
     { 
      FileInfo fi = new FileInfo(_filename); 
      using (StreamReader sr = new StreamReader(fi.Open(FileMode.Open, FileAccess.Read, FileShare.None))) 
      { 
       String readline; 
       while ((readline = sr.ReadLine()) != null) 
       { 
        var line = (from l in readline.Split(_splitChar, StringSplitOptions.None) 
           select l.Trim()).ToList(); 
        Lines.Add(line); 
       } 
      } 
     } 
    } 

class Program 
    { 
     static void Main(string[] args) 
     { 
      var pipeline = new Pipeline() 
      .Register(new FilterCsvFileLoader<FilenameObject, CSVFile>()); 
     } 
    } 
संकलन नहीं होगा 0

अपवाद ऊपर

त्रुटि 2 तर्क 1 .Register लाइन पर है: करने के लिए 'BusinessLogic.IFilter<BusinessObjects.IBusinessObject,BusinessObjects.IBusinessObject>'
सी से 'BusinessLogic.FilterCsvFileLoader<BusinessObjects.FilenameObject,BusinessObjects.CSVFile>' परिवर्तित नहीं कर सकते: \ Users \ davidc \ Documents \ दृश्य स्टूडियो 2010 \ परियोजनाओं \ MPMeFeed \ TestConsole \ Program.cs 15 से 23 TestConsole

उत्तर

5

समस्या आप यहाँ है FilterCsvFileLoader<FilenameObject, CSVFile> औजार IFilter<FilenameObject, CSVFile> जो IFilter<IBusinessObject, IBusinessObject> भी FilenameObject हालांकि & CSVFile की एक व्युत्पन्न प्रकार नहीं है IBusinessObject से प्राप्त कर रहे है।

यह एक आम गलती है। इस के बजाय तरह

कोशिश कुछ:

public interface IFilter 
{ 
    IBusinessObject Execute(IBusinessObject input); 
} 

public interface IFilter<T, U> : IFilter 
    where T : IBusinessObject 
    where U : IBusinessObject 
{ 
    U Execute(T input); 
} 

public abstract class FilterBase<T, U> : IFilter<T, U> 
    where T : IBusinessObject 
    where U : IBusinessObject, new() 
{ 
    protected abstract U Process(T input); 

    IBusinessObject IFilter.Execute(IBusinessObject input) 
    { 
     return this.Execute((T)input); 
    } 

    public U Execute(T input) 
    { 
     return Process(input); 
    } 
} 

public interface IPipeline 
{ 
    IBusinessObject Execute(IBusinessObject input); 

    IPipeline Register<T, U>(IFilter<T, U> filter) 
     where T : IBusinessObject 
     where U : IBusinessObject; 
} 

public class Pipeline : IPipeline 
{ 
    private List<IFilter> _filters = new List<IFilter>(); 

    public IBusinessObject Execute(IBusinessObject input) 
    { 
     var result = input; 
     foreach (var filter in _filters) 
     { 
      result = filter.Execute(result); 
     } 
     return result; 
    } 

    public IPipeline Register<T, U>(IFilter<T, U> filter) 
     where T : IBusinessObject 
     where U : IBusinessObject 
    { 
     _filters.Add(filter); 
     return this; 
    } 
} 
+0

लिए धन्यवाद, और क्यों यह काम नहीं किया है के रूप में एक अच्छा विवरण। – BlueChippy

0

मुझे लगता है कि जब भी मैं एक स्थिति है जहाँ कई अज्ञात या अप्रत्याशित में चलाने प्रकार शामिल हैं हमारे दोस्त object खेल में आता है। यह आपके लिए काम कर सकता है।

यह कुछ अपनी ओर से खुदाई लग सकता है लेकिन वहाँ कोर बुनियादी ढांचे मेरी सेवा बस द्वारा प्रयोग किया जाता विधानसभाओं में एक सामान्य पाइपलाइन दिया गया है:

http://shuttle.codeplex.com/

वर्ग विधानसभा में ObservablePipeline है Shuttle.Core.infrastructure

यह आपको कुछ विचार दे सकता है।

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