2014-03-28 66 views
3

的C#Neo4JClient有GraphClient,你必須調用.Connect()ASP.NET和Neo4jClient - 在哪裏存儲連接?

var client = new GraphClient(new Uri("http://localhost:7474/db/data")); 
client.Connect(); 

在所有我見過的例子,它在一個控制檯應用程序,所以他們在Main()聲明GraphClient並重新使用它。文檔中提到了它的線程安全,並且每個數據庫只有一個實例,並且不會多次調用.Connect()

但是在ASP.NET應用程序中呢?我是否應該將它粘貼到頁面訪問的某個靜態類中(或將其存儲在應用程序狀態中)?就像這樣:

public class DbConnection 
{ 
    private static GraphClient _client; 
    public static GraphClient GraphClient 
    { 
     get 
     { 
      if (_client == null) 
      { 
       _client = new GraphClient(new Uri("http://localhost:7474/db/data")); 
       _client.Connect(); 
      } 
      return _client; 
     } 
    } 
} 

然後在任何ASPX頁面我可以簡單地:

protected void Page_Load(object sender, EventArgs e) 
{ 
    GraphClient client = DbConnection.GraphClient; 
    //do whatever I need to with client 
} 

還是我不理解的是正確的,並會導致各種問題?我是否需要調用每個方法.Connect()(或每頁面的生命週期也許一次),像這樣:

private GraphClient _client; 
private GraphClient PageGraphClient 
{ 
    get { //same as in previous, check if null and load _client with the connection } 
} 

protected void Page_Load(object sender, EventArgs e) 
{ 
    //do whatever I need to with PageGraphClient 
} 

protected void btnSave_Click(object sender, EventArgs e) 
{ 
    //do whatever I need to with PageGraphClient 
} 

等等?我想我只是掛斷了整個線程安全的事情,並「與數據庫建立了太多的連接」,並希望確保我不會錯過簡單/正確的方式來完成此任務。

(是的,我知道我不應該叫直接從ASPX頁面的數據庫命令,我是過度簡化的理解GraphClient類是如何工作的緣故)

+0

你對依賴注入有什麼感受?你以前做過 - 你使用它舒服嗎? –

+0

@ chris-skardon我以前不必這麼做,但如果這是正確的方法,我願意學習新的東西嗎? –

+0

好的 - 這是ASP.NET aspx項目還是MVC項目? –

回答

3

設置使用Ninject(DI框架)構建項目:

  • 爲您的MVC版本添加Ninject.MVC nuget包(即Ninject。MVC5等)
  • 添加Neo4jClient包(雖然我想象你已經有這個)
  • 胡克Ninject,所以它知道一個IGraphClient是什麼

我使用一個模塊對於這一點,所以這個類添加到你的項目(通常是我讓他們在App_Start文件夾名爲「模塊」的子文件夾 - 但它可以在任何地方):

public class Neo4jModule : NinjectModule 
{ 
    /// <summary>Loads the module into the kernel.</summary> 
    public override void Load() 
    { 
     Bind<IGraphClient>().ToMethod(InitNeo4JClient).InSingletonScope(); 
    } 

    private static IGraphClient InitNeo4JClient(IContext context) 
    { 
     var neo4JUri = new Uri(ConfigurationManager.ConnectionStrings["Neo4j"].ConnectionString); 
     var graphClient = new GraphClient(neo4JUri); 
     graphClient.Connect(); 

     return graphClient; 
    } 
} 

我們加載了GraphClient在一個單獨的範圍,你可以閱讀關於此處:Object Scopes

現在我們只需要告訴Ninject加載模塊,所以在NinjectWebCommon.cs文件(在App_Start文件夾)編輯RegisterServices方法(在文件的底部),所以它看起來像:

/// <summary> 
/// Load your modules or register your services here! 
/// </summary> 
/// <param name="kernel">The kernel.</param> 
private static void RegisterServices(IKernel kernel) 
{ 
    kernel.Load<Neo4jModule>(); 
} 
  • 注入到控制器

哪個是添加一個構造(或修改現有的一個)的情況下,採取一個IGraphClient實例:

private readonly IGraphClient _graphClient; 
public HomeController(IGraphClient graphClient) 
{ 
    _graphClient = graphClient; 
} 

現在控制器具有GraphClient的實例作爲使用,當它爲所欲爲:

public ActionResult Index() 
{ 
    ViewBag.NodeCount = _graphClient.Cypher.Match("n").Return(n => n.Count()).Results.Single(); 

    return View(); 
} 

顯然這個擴展,你可以添加一個基地Neo4jController其需要的Neo4j覆蓋所有控制器。

+0

好吧,很酷,很有意義,謝謝!我將閱讀所有這些內容,但是我留下的一個問題更多的僅僅是爲了我自己的教育,那就是:這是否保持Neo4jClient連接在應用程序的整個生命週期中保持開放,或者向控制器發出每個請求行動,還是如何工作?我只是好奇。 –

+0

'對象範圍'鏈接將幫助你,但有四個選項,瞬變 - 每次請求時創建新實例,單例 - 每個請求只創建並返回單個實例,線程 - 每個線程一個實例,請求 - 每個Web請求一個實例,請求結束時銷燬。 –

+0

對,我得到,對不起,我可能沒有正確地問它,我想知道更多,Neo4jClient的最佳做法是保持一個連接打開,或者它應該不斷打開和關閉每個請求的連接。我沒有看到任何類似MongoDB C#驅動程序爲您處理的連接池選項,所以我只是想了解是否需要在此基礎上構建這些內容。 –