2011-04-05 52 views
4

我正試圖爲Ravendb實現IoC(Ninject),並且遇到了一點小麻煩。我使用http://www.dotnetguy.co.uk/post/2010/06/12/raven-db-ndash-part-1-ndash-documentsession-per-request-with-structuremap的代碼提供幫助。需要幫助獲取Ninject等效的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因爲新的構造函數而在每個請求上都爲null。

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

感謝任何花時間嘗試和幫助解釋的人。

回答

1

相反的new RavenSessionFactoryBuilder().GetSessionFactory()....,我想你會想:

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

,你已經做了這樣的事情事先:

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

聲明:我從來沒有嘗試GetBind聲明之前。您可能需要工廠方法。

+0

我擺脫了我的界限,並添加了你提到的2行。我現在得到一個錯誤「錯誤激活IDocumentSession。沒有匹配的綁定可用,並且類型不可自行綁定....」 – Ryan 2011-04-05 23:08:02

+0

這隻意味着您需要爲'IDocumentSession'添加一個綁定,例如'Bind < IDocumentSession>()。到();'你更近了一步。 – neontapir 2011-04-06 03:48:58

+0

現在我越來越接近了。我有與IDatabaseCommands相同的錯誤。似乎沒有什麼東西想與它綁定。 http://pastebin.com/U2qyf51m – Ryan 2011-04-06 11:59:55

0

Ninject基本上有5個選項範圍。

TransientScope - 你使用意味着一個新的實例爲

SingletonScope每個請求創建一個 - 是有史以來唯一的一個實例

ThreadScope - 只有每個線程創建一個實例

RequestScope - 只有一個實例是每HttpRequest的創建

自定義 - 您提供的範圍對象

如果你正在創建你可以指定.InRequestScope()如果它是一個Windows應用程序的web應用程序,你可以指定.InThreadScope()

最後,如果你必須指定一個混合(我不能完全肯定它的工作原理結構圖),你可能會做.InScope(ctx => HttpRequest.Current != null ? HttpRequest.Current : Thread.CurrentThread)

+0

感謝一步一步的指導。在我的問題中,我犯了一個錯誤,並將InTransientScope()而不是RequestScope()。問題在於,由於新的構造函數,_ravenSessionFactory在每個請求上都是空的。 SM每次都使用相同的實例(它出現) – Ryan 2011-04-05 21:47:58

13

工廠被稱爲Ninject的供應商。轉換SessionFactorySessionProvider: -

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