0

我有一个使用 RavenDB 作为数据存储的 MVC4 应用程序。该应用程序具有 MVC/Web、域、数据和安全层。

我正在编写需要初始化数据库和访问 DocumentStore 的自定义成员资格和角色提供程序。我正在从安全层编写这些类,并且想使用单例 DocumentStore(在应用程序中设置),但我不知道如何访问它。

其他,我看到为 RavenDB 编写自定义提供程序的示例在 Provider.Initialize() 方法中创建新的 DocumentStore 实例,但这似乎违反了每个服务器拥有一个 DocumentStore 的规则。

目前,我在 Application_Start() 中创建了 RavenDB DocumentStore 的单个实例。我在处理 DocumentStore.Session(s) 的 MVC/Web 层中有一个基本控制器。

有没有办法做到这一点?我应该将我的安全逻辑移动到 MVC/Web 层以简化事情吗?

4

2 回答 2

1

您可能想要使用某种依赖注入,或者通过使用 TinyIoC 等自动工具或手动执行此操作。

例如,看看 RaccoonBlog 如何做到这一点。首先,它在 Application_Start 创建一个 DocumentStore 实例,并将该引用存储在各种基类的静态变量中:

https://github.com/ayende/RaccoonBlog/blob/master/RaccoonBlog.Web/Global.asax.cs#L66

然后,每当新会话开始时,它就会注入一个新的 Session 对象:

https://github.com/ayende/RaccoonBlog/blob/master/RaccoonBlog.Web/Global.asax.cs#L31

这个项目是从 Controller 基类中提取的:

https://github.com/ayende/RaccoonBlog/blob/master/HibernatingRhinos.Loci.Common/Controllers/RavenController.cs#L16

我会做得更好一点,通过使用适当的 IoC 或至少不使用 Items 字典,但你明白了。

只需在公共地方保存一个 DocumentStore 并将开放会话注入基类

于 2013-10-13T13:31:43.863 回答
0

我使用单例模式提出了自己的解决方案。

我所做的是在我的应用程序的数据层中创建一个暴露公共 IDocumentStore 属性的单例。它使用一个静态构造函数,该构造函数在第一次请求静态属性时运行(在 Application_Start 中执行),然后实例化一个 IDocumentStore 对象。然后在基本控制器和我的应用程序的其他层(如安全层 f.ex.)中为每个对 DocStore.Instance 的引用返回初始实例

public sealed class DocStore
{
    protected static readonly IDocumentStore instance;

    static DocStore()
    {
        // instantiate documentStore
        instance = new DocumentStore { ConnectionStringName = Constants.ConnectionStrings.XXXXX };
        instance.Initialize();

        // instantiate tenants
        try
        {
            instance.DatabaseCommands.EnsureDatabaseExists(Constants.Tenants.XXXXX);
        }
        catch (Exception ex)
        {

            //TODO: catch exception
            throw ex;
        }

        // initialize indexed
        try
        {
            InitializeIndexes(instance);
        }
        catch (Exception ex)
        {

            //TODO: catch exception
            throw ex;
        }
    }

    private DocStore()
    {

    }

    public static IDocumentStore Instance
    {
        get { return instance; }
    }

    private static void InitializeIndexes(IDocumentStore store)
    {
        // builds all indexes defined in XXXXX.Data.dll
        var dataCatalog = new CompositionContainer(new AssemblyCatalog(typeof(DocStore).Assembly));
        IndexCreation.CreateIndexes(dataCatalog,
                                    store.DatabaseCommands.ForDatabase(Constants.Tenants.XXXXX),
                                    store.Conventions);
    }
}
于 2013-10-13T20:25:29.083 回答