私は直面している設計上の問題を解決する良い解決策を見つけることができません。現在、私はクエリ文字列を解析するシステムを設計しています。汎用/継承に関する設計上の問題
各パーサは、インタフェースIQueryParserを実装する必要があります。私は、HTTPリクエストを受信すると
public interface IQueryParser
{
Query Parse();
}
、私は工場を使用してそれを解析することができパーサを探してみてください。 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も渡すことです。私のユースケースを処理するために私のアプリケーションをどのように再設計することができるかについてのヒント/アイデア?コメントで述べたように
は、 セバスチャン
実際、1つの解決策はすべてのパーサーをインスタンス化して工場に渡すことです。その後、各パーサーはCanParseメソッドを実装する必要があります。理想的ではないが、そのトリックをするだろうか?より良いオプションはありますか? – Seb
私はちょうどランタイム値(https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=99)を注入することに関する良い記事を読んだ。これに基づいて、コンストラクタを介してコンテキストの注入を再考することができます。 –
私はあなたの 'CanParse()'ソリューションを以前から使っていました(http://stackoverflow.com/questions/28578105/design-pattern-oraccepted-solutions-for-avoiding-switching-on-types/28580610#28580610) 。それは動作しますが、どこかに良い方法があると確信しています... –