Question

I am trying to use Ninject 3 Convention-based bindings, and would like to specify which lifestyle a service should be bound with at bind-time.

I am trying to use the code below, without success; my app errors saying that my services haven't been bound. I know I can write my own binder and do all of the reflection work myself, but this looked rather nice. Am I missing something?

Kernel.Bind(x => x.FromAssembliesMatching("PatentSpoiler*")
      .SelectAllClasses()
      .BindDefaultInterface()
      .Configure(cfg =>
       {
          cfg.InTransientScope();
          cfg.WhenClassHas<BindAsASingletonAttribute>().InSingletonScope();
          cfg.WhenClassHas<BindInRequestScopeAttribute>().InRequestScope();
       }));

Thanks,

Jon

Was it helpful?

Solution

In the Configure callback you are putting together a configuration which is used on all bindings and when you write multiple WhenClassHas and In...Scope statements you are basically overriding your own settings so all your type bindings will use the last statement cfg.WhenClassHas<BindInRequestScopeAttribute>().InRequestScope();.

To solve this you need to use the second overload of Configure where you get the currently bound type and based on its attributes register your type with the correct scope:

using Ninject.Infrastructure.Language; //needed for HasAttribute<T>

//...

Kernel.Bind(x => x.FromAssembliesMatching("PatentSpoiler*")
      .SelectAllClasses()
      .BindDefaultInterface()
      .Configure((cfg, type) =>
      {
          if (type.HasAttribute<BindAsASingletonAttribute>())
              cfg.InSingletonScope();
          else if (type.HasAttribute<BindInRequestScopeAttribute>())
              cfg.InRequestScope();
          else
              cfg.InTransientScope();
      }));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top