0

I have two classes which depend on each other. Obviously, when I use ninject in the following way:

public Class Class1()
{
  private readonly class2;
  public Class1(IClass2 class2)
  {
    this.class2 = class2;
  }
}

public Class Class2()
{
  private readonly class1;
  public Class1(IClass1 class1)
  {
    this.class1 = class1;
  }
}

It results in a cyclic dependency.

I know that the way to solve this problem is property injection. But I tried this:

public Class Class1()
{
  private readonly class2;
  public Class1()
  {
  }
  [Inject]
  IClass2 Class2
  {
   get { return this.class2; }
   set { this.class2 = value; }
  }
}

in combination with this:

public Class Class2()
{
  private readonly class1;
  public Class1(IClass1 class1)
  {
    this.class1 = class1;
  }
}

And the reversed way, when I inject in the second one with property and in the first with constructor. Both of them result in a cyclic dependency. The third way, when I use property injection in both of them, results in a StackOverflow exception. What is the way to implement this type of injection? Keeping in mind that both of these are service classes.

Binding:

/// <summary>
        /// Creates the kernel that will manage your application.
        /// </summary>
        /// <returns>The created kernel.</returns>
        private static IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            try
            {
                kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
                kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

                RegisterServices(kernel);
                return kernel;
            }
            catch
            {
                kernel.Dispose();
                throw;
            }
        }

        /// <summary>
        /// Load your modules or register your services here!
        /// </summary>
        /// <param name="kernel">The kernel.</param>
        private static void RegisterServices(IKernel kernel)
        {
            kernel.Bind(b => b
            .From(Assemblies.ProjectServices) // link to the services there
            .SelectAllClasses()
            .BindDefaultInterface());
        } 
StefanL19
  • 1,476
  • 2
  • 14
  • 29

1 Answers1

1

I think that you can try to use other Object Scopes when you register Class1 and Class2 instead of the deafult one (InTransientScope()).

Something like this (I used singleton scope here for example):

 kernel.Bind<IClass1>().To<Class1>().InSingletonScope();
 kernel.Bind<IClass2>().To<Class2>().InSingletonScope();

Also I think that it will only work if you will use property injection for both classes and not only in one of them, you should try both options.

As a side note I do think that a cyclic dependency is a big hint that you are missing something in your design and you should condiser redesigning these classes.

YuvShap
  • 3,825
  • 2
  • 10
  • 24
  • Did you try using Singleton scope, What if actual program cannot work with Singleton instance, but need a unique object – Mrinal Kamboj Oct 21 '16 at 09:41
  • @MrinalKamboj I don't undertand what is the probelm, you can choose from the already existing scopes the one who answers yours needs and if thre isn't any you can create a custom one, the singleton scope was just for the example. – YuvShap Oct 21 '16 at 23:46