【问题标题】:Need help getting Ninject equivalent for StructureMap syntax需要帮助获得与 StructureMap 语法等效的 Ninject
【发布时间】:2011-07-30 08:17:55
【问题描述】:

我正在尝试为 Ravendb 实现 IoC (Ninject),但遇到了一些障碍。我正在使用来自http://www.dotnetguy.co.uk/post/2010/06/12/raven-db-ndash-part-1-ndash-documentsession-per-request-with-structuremap 的代码来提供帮助。

public interface IRavenSessionFactoryBuilder
{
    IRavenSessionFactory GetSessionFactory();
}

public class RavenSessionFactoryBuilder : IRavenSessionFactoryBuilder
{
    private IRavenSessionFactory _ravenSessionFactory;

    public IRavenSessionFactory GetSessionFactory()
    {
        return _ravenSessionFactory ?? (_ravenSessionFactory = CreateSessionFactory());
    }

    private static IRavenSessionFactory CreateSessionFactory()
    {
        Debug.Write("IRavenSessionFactory Created");
        return new RavenSessionFactory(new DocumentStore
                                           {
                                               Url =
                                                   System.Web.Configuration.WebConfigurationManager.AppSettings[
                                                       "Raven.DocumentStore"]
                                           });
    }
}

public interface IRavenSessionFactory
{
    IDocumentSession CreateSession();
}

public class RavenSessionFactory : IRavenSessionFactory
{
    private readonly IDocumentStore _documentStore;

    public RavenSessionFactory(IDocumentStore documentStore)
    {
        if (_documentStore != null) return;
        _documentStore = documentStore;
        _documentStore.Initialize();
    }

    public IDocumentSession CreateSession()
    {
        Debug.Write("IDocumentSession Created");
        return _documentStore.OpenSession();
    }
}

我不确定如何转换以下结构映射语法。

ObjectFactory.Configure(x => x.For<IDocumentSession>()
                  .HybridHttpOrThreadLocalScoped()
                  .AddInstances(inst => inst.ConstructedBy
                    (context => context.GetInstance<IRavenSessionFactoryBuilder>()
                      .GetSessionFactory().CreateSession())));

在我的尝试中,由于新的构造函数,_ravenSessionFactory 在每个请求上都为空。

Bind<IDocumentSession>().ToMethod(
            x => new RavenSessionFactoryBuilder().GetSessionFactory().CreateSession()).RequestScope();

感谢任何花时间尝试帮助解释的人。

【问题讨论】:

    标签: c# ioc-container structuremap ninject ravendb


    【解决方案1】:

    Ninject 基本上有 5 个作用域选项。

    TransientScope - 您正在使用的意思是为每个请求创建一个新实例

    SingletonScope - 只创建一个实例

    ThreadScope - 每个线程只创建一个实例

    RequestScope - 每个 HttpRequest 只创建一个实例

    自定义 - 您提供范围对象

    如果您正在创建 Web 应用程序,您可以指定 .InRequestScope() 如果它是 Windows 应用程序,您可以指定 .InThreadScope()

    最后,如果你必须指定一个混合体(我不完全确定它在结构图中是如何工作的)你可以这样做.InScope(ctx =&gt; HttpRequest.Current != null ? HttpRequest.Current : Thread.CurrentThread)

    【讨论】:

    • 谢谢。在我的问题中,我犯了一个错误,并把 InTransientScope() 而不是 RequestScope()。问题是由于新的构造函数,每个请求的 _ravenSessionFactory 都是空的。 SM 每次都使用同一个实例(出现)
    【解决方案2】:

    我想你想要的不是new RavenSessionFactoryBuilder().GetSessionFactory()....

    Kernel.Get<IRavenSessionFactoryBuilder>().GetSessionFactory()....
    

    你事先做过这样的事情:

    Bind<IRavenSessionFactoryBuilder>().To<IRavenSessionFactoryBuilder>()
      .InSingletonScope();
    

    免责声明:我之前从未在 Bind 声明中尝试过 Get。你可能需要一个工厂方法。

    【讨论】:

    • 我删除了我的行并添加了您提到的 2 行。我现在收到一个错误“激活 IDocumentSession 时出错。没有匹配的绑定可用,并且类型不是自绑定的......”
    • 这只是意味着你需要为IDocumentSession添加一个绑定,比如Bind&lt;IDocumentSession&gt;().To&lt;DocumentSession&gt;();你更近了一步。
    • 我现在肯定越来越近了。我对 IDatabaseCommands 有同样的错误。似乎没有什么想要与之绑定的。 pastebin.com/U2qyf51m
    • 我对 RavenDB 一无所知。但是,在阅读和查看上述内容时,IDocumentSession 应该使用ToMethod 绑定到ravenSessionFactory.CreateSession()。这应该绕过绑定IDatabaseCommands的需要。
    • 我做了更多的研究。假设你在 MVC 中运行,我想你只想要 Bind&lt;IDocumentSession&gt;().ToMethod(context =&gt; context.GetInstance&lt;IRavenSessionFactoryBuilder&gt;().GetSessionFactory().CreateSession());
    【解决方案3】:

    工厂在 Ninject 中被称为提供者。将SessionFactory 转换为SessionProvider:-

    public class RavenSessionProvider : Provider<IDocumentSession>
    {
        private readonly IDocumentStore _documentStore;
    
        public RavenSessionFactory(IDocumentStore documentStore)
        {
            _documentStore = documentStore;
        }
    
        public IDocumentSession GetInstance(IContext ctx)
        {
            Debug.Write("IDocumentSession Created");
            return _documentStore.OpenSession();
        }
    }
    

    还将您的 RavenSessionFactoryBuilder 更改为 DocumentStoreProvider:-

    public class DocumentStoreProvider : Provider<IDocumentStore>
    {
        public IDocumentStore GetInstance(IContext ctx)
        {
            var store = new DocumentStore 
                       { Url = System.Web.Configuration.WebConfigurationManager.AppSettings["Raven.DocumentStore"]});
            store.Initialize();
            return store;
        }
    }
    

    并添加绑定:

    Bind<RavenSessionProvider>().ToSelf().InSingletonScope()
    Bind<IDocumentSession>().ToProvider<RavenSessionProvider>();
    

    【讨论】:

      【解决方案4】:

      您不需要创建工厂或提供者等来执行此操作。

      Ninject 为每个请求执行会话,为您创建一个 Ninject 模块,该模块在 InSingletonScope() 中绑定一个文档存储,然后在请求范围内绑定一个 DocumentSession 并准备就绪。

      我已经写了一个关于 Ninject 和 RavenDB 的分步指南

      http://www.dalsoft.co.uk/blog/index.php/2012/04/12/mvc-get-ravendb-up-and-running-in-5-minutes-using-ninject/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-04
        • 1970-01-01
        • 1970-01-01
        • 2020-11-07
        • 2014-06-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多