StructureMap“条件单例”用于 Lucene.Net IndexReader

发布于 2024-10-17 04:51:26 字数 278 浏览 6 评论 0原文

我有一个线程安全对象,它的创建成本很高,并且需要通过我的应用程序(Lucene.Net IndexReader)来使用。

该对象可能会变得无效,此时我需要重新创建它(IndexReader.IsCurrent 为 false,需要使用 IndexReader.Reopen 的新实例)。

我希望能够使用 IoC 容器 (StructureMap) 来管理对象的创建,但我无法确定这种情况是否可行。感觉就像某种“条件单例”生命周期。

StructureMap提供这样的功能吗? 还有其他建议吗?

I have a threadsafe object that is expensive to create and needs to be available through my application (a Lucene.Net IndexReader).

The object can become invalid, at which point I need to recreate it (IndexReader.IsCurrent is false, need a new instance using IndexReader.Reopen).

I'd like to able to use an IoC container (StructureMap) to manage the creation of the object, but I can't work out if this scenario is possible. It feels like some kind of "conditional singleton" lifecycle.

Does StructureMap provide such a feature?
Any alternative suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

转身以后 2024-10-24 04:51:26

我可能会使用 PerRequest 范围,而不直接返回 IndexReader 。相反,我会返回 IndexReader 的抽象,它将对类级别上保存的静态引用执行检查。

然后,当访问 shim/proxy/abstraction 上的属性时,它将检查静态引用(当然,您将使其成为线程安全的)并在交付之前根据需要重新获取 IndexReader它返回给用户。

I would probably use a scope of PerRequest and not return the IndexReader directly. Instead, I'd return an abstraction of the IndexReader which would perform a check on a static reference held on the class level.

Then, when your property on the shim/proxy/abstraction is accessed, it would check the static reference (you would make it thread-safe, of course) and re-get the IndexReader if needed before delivering it back to the user.

凡尘雨 2024-10-24 04:51:26

最后,我选择了一个简单的代理对象,它包装了实际的 IndexReader 并管理重新打开。由于我需要在请求之间使用相同的实例,因此我使用 StructureMap 来提供它的单例实例。代码如下。

我已经研究过创建自定义 StructureMap ILifecycle 来处理这种情况,但没有走得太远,请参阅此问题

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)
        );

In the end I have gone for a simple proxy object that wraps the actual IndexReader and manages the Reopening. As I need to use the same instance of this across requests I am using StructureMap to provide a singleton instance of it. Code below.

I've investigated creating a custom StructureMap ILifecycle to handle this situation, but didn't get to far, see 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;
        }
    }
}

And the StructureMap registration:

For<IndexReaderProxy>().Singleton().Use(
            new IndexReaderProxy(FSDirectory.Open(new DirectoryInfo(LuceneIndexPath)), true)
        );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文