1

我已经设置了一个 NInject(使用 1.5 版)绑定,如下所示:

Bind<ISessionFactory>().ToMethod<ISessionFactory>(ctx => 
{
    try
    {
        // create session factory, might fail because of database issues like wrong connection string
    }
    catch (Exception e)
    {
        throw new DatabaseException(e);
    }
}).Using<SingletonBehavior>();

如您所见,此绑定使用单例行为,但也可能在未正确配置某些内容时引发异常,例如与数据库的错误连接字符串。

现在,当会话工厂的创建首先失败(抛出数据库异常)时,NInject 不会尝试再次创建对象,但总是返回 null。

我需要 NInject 首先检查 null 并在实例为 null 时重新创建,但当然不是在已经成功构造实例时(保持它为单例)。像这样:

var a = Kernel.Get<ISessionFactory>(); // might fail, a = null
// ... change some database settings
var b = Kernel.Get<ISessionFactory>(); // might not fail anymore, b = ISessionFactory object

我需要编写自定义行为还是缺少其他内容?

4

1 回答 1

1

这没有多大意义。

首先,单例的要点是依赖于该项目的所有内容都应该看到完全相同的东西——如果你的工厂方法要改变主意,这很难实现。

此外,如果您在谈论 NHibernate ISessionFactory(您是吗?),它不会出现可以恢复的这种性质的短暂故障(或者如果可以,您能否解释原因 - 我不是这方面的专家)。我很欣赏 Session 的创建可能会失败(但您不会将其保留为单例),但这与创建工厂失败的情况完全不同(如果您不能依靠工厂来拥有愚蠢的构造函数,那么您能做什么?依靠?)。

就 NInject 的角度而言,创建方法(无论是工厂还是提供者)与范围是分开的,所以我怀疑是否会有一种方法可以干净地管理您想要做的事情(即使您可以解决开头的两个问题)。我强烈建议您查看源代码 - 它简短而干净,因此如果有答案,它会立即跳出来。下载时间不会超过一分钟 - 去做吧!

最后,一篇关于管理 NHibernate 会话的好文章(哪个 IIRC 没有为会话工厂创建失败做出任何规定)

现在,要实际回答这个问题,不管它是否是一个坏问题——如果在创建工厂时有可能发生故障,并且您无法调整工厂以不这样做(您有多少重试看起来看到创建工厂?),答案是您将重试逻辑(用于创建工厂)移动到负责创建会话的提供程序或方法中,然后可以以您认为合适的方式重试。

于 2010-04-06T08:25:41.480 回答