[英]Design issue with generic/inheritance
我找不到解决我面临的设计问题的好方法。 目前,我正在设计一个应该解析查询字符串的系统。
每个解析器都必须实现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。 关于如何重新设计应用程序以处理用例的任何提示/想法?
谢谢塞巴斯蒂安
如评论中所述, QueryContext context
是运行时数据,不应注入到您的对象中。
您可以使用您提到的CanParse
解决方案,也可以使用以下替代方法:
public interface IQueryParser
{
Maybe<Query> Parse(QueryContext context);
}
Maybe<T>
结构用于支持返回值“ no value”(这比返回null
Query
“ no value”更容易理解和诚实)。 在此处查看更多信息: http : //enterprisecraftsmanship.com/2015/03/13/functional-c-non-nullable-reference-types/
如果该接口的实现无法解析,则应返回“无值”。
现在,消费者得到了一个已经建立的无状态解析器的集合,如下所示:
public class Consumer
{
private readonly IQueryParser[] parsers;
public Consumer(IQueryParser[] parsers)
{
//..
}
}
并且每次调用它时,它都会尝试所有解析器,直到找到可以解析查询的解析器为止:
var result =
parsers
.Select(x => x.Parse(context))
.FirstOrDefault(x => x.HasValue); //the default of the `Maybe` struct is a "no value"
if(result.HasValue) //some parse was able to parse
//...
else
//..
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.