我正在尝试实现一个过滤器/管道模式,以便我可以接收输入,通过多个过滤器处理它并在最后获得输出。
当输入类型和最终输出类型相同且每个过滤器也使用相同类型时,我可以轻松完成此操作。但是,我想输入一种类型并获得另一种类型。
e.g。 按文件名获取csvfile,将其加载到单个字符串中,解析它们,验证并输出为xml。伪代码示例:
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, FilterBase, FilterImplementation
IPipeline, Pipeline
IBusinessObject, BusinessObject, BusinessObjectImplementation
我的目的是能够获得IFilter<T,U>
T and U are IBusinessObject
但是,在尝试向列表中添加BusinessObjectImplementation
时,我收到“无法从IBusinessObject
转换为IFilter<IBusinessObject, 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>());
}
}
例外情况在上面的.Register行
错误2参数1:无法转换 '
BusinessLogic.FilterCsvFileLoader<BusinessObjects.FilenameObject,BusinessObjects.CSVFile>
' 至 'BusinessLogic.IFilter<BusinessObjects.IBusinessObject,BusinessObjects.IBusinessObject>
'
C:\ Users \ davidc \ Documents \ Visual Studio 2010 \ Projects \ MPMeFeed \ TestConsole \ Program.cs 15 23 TestConsole
答案 0 :(得分:6)
您遇到的问题是FilterCsvFileLoader<FilenameObject, CSVFile>
实现了IFilter<FilenameObject, CSVFile>
,即使IFilter<IBusinessObject, IBusinessObject>
&amp; 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;
}
}
。
这是一个常见的错误。
尝试这样的事情:
{{1}}
答案 1 :(得分:0)
我发现每当遇到涉及许多未知或不可预测类型的情况时,我们的朋友object
就会发挥作用。这可能对你有用。
您可能需要进行一些挖掘,但我的服务总线使用的核心基础架构组件中有一个通用的管道实现:
汇编ObservablePipeline
Shuttle.Core.infrastructure
它可能会给你一些想法。