Question

The C# Neo4JClient has GraphClient where you have to call .Connect()

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

In all of the examples that I've seen, it's in a Console app, so they declare GraphClient in Main() and re-use it. And the documentation mentions how its Thread Safe and to only have one instance per database and to not call .Connect() multiple times.

But what about in ASP.NET applications? Should I be sticking it in some static class that is accessed by the pages (or store it in the Application state)? Like this:

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;
        }
    }
}

And then in any ASPX page I could simply:

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

Or am I not understanding that correctly, and that would cause all kinds of problems? Do I need to call .Connect() in each method (or maybe once per page lifecycle), like so:

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
}

And so on? I guess I'm just getting hung up on the whole Thread Safe thing and "making too many connections to the db" and wanting to make sure I'm not missing an easy/correct way to do this.

(and yes, I know that I shouldn't be calling the database commands from the ASPX pages directly, I'm over-simplifying for the sake of understanding how the GraphClient class works ;)

Was it helpful?

Solution

To set up your project with Ninject (DI framework):

  • Add the Ninject.MVC nuget package for your MVC version (i.e. Ninject.MVC5 etc)
  • Add the Neo4jClient package (though I imagine you already have this)
  • Hook up Ninject so it knows what an IGraphClient is

I use a Module for this, so add this class to your project (usually I have them in a sub-folder called ‘Modules’ in the App_Start folder – but it can be anywhere):

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;
    }
}

We've loaded the GraphClient in a singleton scope which you can read all about here: Object Scopes

Now we just need to tell Ninject to load the module, so in the NinjectWebCommon.cs file (in the App_Start folder) edit the RegisterServices method (at the bottom of the file) so it looks like:

/// <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>();
} 
  • Inject into the controller

Which is a case of adding a constructor (or modifying an existing one) to take an IGraphClient instance:

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

Now the controller has an instance of the GraphClient to use as and when it pleases:

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

    return View();
}

Obviously extending this, you could add a base Neo4jController which any controllers requiring Neo4j override.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top