我找不到解决我所面临的设计问题的好方案。目前我正在设计一个系统应该解析查询字符串。通用/继承设计问题
每个解析器必须实现的接口IQueryParser:
public interface IQueryParser
{
Query Parse();
}
当我收到一个HTTP请求时,我试图找到能够使用工厂来分析它的分析器。 QueryContext仅仅是一个简单的的HttpRequest
public interface IQueryParserFactory
{
void Register<TQueryParser>(Func<QueryContext, bool> predicate)
where TQueryParser : IQueryParser;
IQueryParser Create(QueryContext context);
}
public class QueryParserFactory : IQueryParserFactory
{
private readonly ConcurrentDictionary<Type, Func<QueryContext, bool>> _parsers = new ConcurrentDictionary<Type, Func<QueryContext, bool>>();
public void Register<TQueryParser>(Func<QueryContext, bool> predicate)
where TQueryParser : IQueryParser
=> _parsers.AddOrUpdate(typeof(TQueryParser), predicate, (key, oldValue) => predicate);
public IQueryParser Create(QueryContext context)
=> (from kpv in _parsers
where kpv.Value.Invoke(context)
select (IQueryParser)Activator.CreateInstance(kpv.Key, context)).FirstOrDefault();
}
版本
解析器可能需要额外的依赖,我不知道如何将它们注入分析器。假设我们有以下解析器..我怎么知道我需要什么具体的IOperatorParser实现?
public class QueryParser : IQueryParser
{
private readonly QueryContext _context;
public QueryParser(QueryContext context, IOperatorParser parser)
{
_context = context;
}
public Query Parse()
{
(...)
}
}
我需要某种依赖注入。问题是我自己实例化对象,并且我也在运行时传递了QueryContext。任何关于如何重新设计我的应用程序来处理我的用例的提示/想法?
谢谢 塞巴斯蒂安
实际上,一种解决方案可能是实例化所有解析器并将它们传递给工厂。然后每个解析器都需要实现一个CanParse方法。不理想,但会做的伎俩?有更好的选择吗? – Seb
我刚刚阅读了一篇关于注入运行时值的好文章(https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=99)。基于此,您可能需要重新考虑通过构造函数注入上下文。 –
我之前使用过'CanParse()'解决方案(http://stackoverflow.com/questions/28578105/design-pattern-or-accepted-solutions-for-avoiding-switching-on-types/28580610#28580610) 。它的作品,但我相信有更好的方式在那里... –