2

I'am working at application in ASP.NET MVC 5 which is supported by Neo4j graph database. I'am using Neo4jClient and Neo4j.AspNet.Identity. To connect with database there is a class called GraphClient. Below is the way to instatiate connection:

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

As far as i know GraphClient is thread safe. It's required have one instance of it. Following this topic ASP.NET and Neo4jClient - where to store the connection? I've used Ninject for resolve this problem. That's the code:

public class Neo4jClient:NinjectModule
{
    public override void Load()
    {
        Bind<IGraphClient>().ToMethod(InitializeNeo4jClient).InSingletonScope();
    }
    private static IGraphClient InitializeNeo4jClient(IContext context )
    {
        var graphClient = new GraphClient(new Uri("http://localhost:7474/db/data"));
        graphClient.Connect();
        return graphClient;
    }
}

Code in NinjectWebCommon.cs

private static void RegisterServices(IKernel kernel)
{
   kernel.Load<Neo4jClient>();
}

Everything seems to be fine but i have a problem with Neo4j.AspNet.Identity In class Startup.Auth.csthere is this code

public partial class Startup
    {

        public void ConfigureAuth(IAppBuilder app)
        {
            // Configure the db context, user manager and signin manager to use a single instance per request
            ConfigureNeo4j(app);
            app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
            app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);


            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Account/Login"),
                Provider = new CookieAuthenticationProvider
                {

                    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                        validateInterval: TimeSpan.FromMinutes(30),
                        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
                }
            });            
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);


            app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));


            app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);


        }
        private void ConfigureNeo4j(IAppBuilder app)
        {
            app.CreatePerOwinContext(() => {
                var gc = new GraphClient(new Uri("http://localhost.:7474/db/data"));
                gc.Connect();
                var gcw = new GraphClientWrapper(gc);
                return gcw;
            });
        }
    }

As You Can See in ConfigureNeo4j(IAppBuilder app) method there is an another instance of GraphClient to pass the context. My question is how can i pass the GraphClient instance from Ninject to this method? How to resolve problem with multiple instance of GraphClient in this case?

Community
  • 1
  • 1
Drozdin
  • 25
  • 5

1 Answers1

0

So there's a couple of things you'll need to do around this, first - as you can see - you use OWIN for the Identity and Ninject for the rest of the site, the easiest approach is to make OWIN know about the Ninject Kernel, aaaand the Ninject Kernel to know about the GraphClientWrapper.

1. Add a binding for GraphClientWrapper to Ninject

Add the following to your NinjectModule:

private GraphClientWrapper(IContext arg) { 
    return new GraphClientWrapper(Kernel.Get<IGraphClient>()); 
}

Add this to the module Load method:

Kernel.Bind<GraphClientWrapper>().ToMethod(GetGraphClientWrapper).InSingletonScope();

NB You do need to have the Kernel.Bind<IGraphClient>() before this (for obvious reasons).

2. Update NinjectWebCommon to have an internal Kernel property

Add:

internal static IKernel Kernel { get; private set; }

and then in the CreateKernel method add:

Kernel = kernel;

just before you return kernel;

3. Bind OWIN to the Ninject Kernel

Finally, change the ConfigureNeo4j method to be:

private void ConfigureNeo4j(IAppBuilder app) {
    app.CreatePerOwinContext(() => NinjectWebCommon.Kernel.Get<GraphClientWrapper>());
}

One instance for all!

Community
  • 1
  • 1
Charlotte Skardon
  • 6,220
  • 2
  • 31
  • 42