最後,我去了一個簡單的代理對象,它包裝了實際的IndexReader並管理了Reopening。因爲我需要在請求中使用同一個實例,所以我使用StructureMap來提供它的單例實例。下面的代碼。
我已經研究過創建一個自定義的StructureMap ILifecycle來處理這種情況,但沒有得到很遠,請參閱this question。
public class IndexReaderProxy
{
private IndexReader _indexReader;
private readonly object _indexReaderLock = new object();
public IndexReaderProxy(Directory directory, bool readOnly)
{
_indexReader = IndexReader.Open(directory, readOnly);
}
public IndexReader GetCurrentIndexReader()
{
ReopenIndexReaderIfNotCurrent();
return _indexReader;
}
private void ReopenIndexReaderIfNotCurrent()
{
if (_indexReader.IsCurrent()) return;
lock (_indexReaderLock)
{
if (_indexReader.IsCurrent()) return;
var newIndexReader = _indexReader.Reopen();
_indexReader.Close();
_indexReader = newIndexReader;
}
}
}
而且StructureMap登記:
For<IndexReaderProxy>().Singleton().Use(
new IndexReaderProxy(FSDirectory.Open(new DirectoryInfo(LuceneIndexPath)), true)
);
我casperOne同意。考慮將實例隱藏在接口/外觀之後,以便更輕鬆地實現諸如對象池的策略。 – Steven 2011-02-09 19:26:48
我考慮過這一點,但從IoC容器中刪除對象創建和生命週期管理的可能性讓人感到羞愧。如果我沒有提出更多以IoC爲中心的話,它肯定會適合我,並且會成爲我的迴歸解決方案。 – 2011-02-09 19:39:38