Trying to get ninject and signalR to work properly - c#

In my NinjectWebCommon.cs file, under the RegisterServices method I have the following:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IProfileRepository>().To<ProfileRepository>();
kernel.Bind<IMatchUpService>().To<MatchUpService>();
kernel.Bind<ISoloUserRepository>().To<SoloUserRepository>();
SignalR.GlobalHost.DependencyResolver = new SignalR.Ninject.NinjectDependencyResolver(kernel);
}
I am trying to inject SoloUserRepository into my hub class, here is my hub class:
public class MatchMaker : Hub
{
[Inject]
private ISoloUserRepository soloUsers { get; set; }
}
For some reason when I try to use the soloUsers object in my Hub class, i get object reference not set to instance of an object because the soloUsers object is never being instantiated or, in other words, not injected. Am I doing something wrong?

Your problem is that you have a private property, and Ninject by default doesn't inject private properties.
So either you make your property public or you can enable non public property injection with:
kernel.Settings.InjectNonPublic = true;
I'm not familiar with the dependency injection in SignalR (so maybe it's not supported) but you should always prefer constructor injection so your Hub should be like:
public class MatchMaker : Hub
{
private readonly ISoloUserRepository soloUsers;
public MatchMaker(ISoloUserRepository soloUsers)
{
this.soloUsers = soloUsers;
}
}

Related

Fail to initialize dependencies. Singleton class using Dependency Injection (Ninject)

I want a singleton class that uses dependency injection (ninject) start as soon as the application starts. The singleton class resides in Domain layer(Class Library) -
Domain.Concrete.Operations. And I'm using this class in WebUI layer(MVC).
I'm stuck at initializing dependencies in static constructor of the service that I plan to start in Application_Start method. What is the right way to do it?
Singleton class:
namespace Domain.Concrete.Operations
{
public sealed class SingletonClass
{
private IInterface1 _iInterface1;
private IInterface2 _iInterface2;
public SingletonClass(IInterface1 iInterface1, IInterface2 iInterface2)
{
this._iInterface1 = iInterface1;
this._iInterface2 = iInterface2;
StartAllOperations();
}
public void StartAllOperations()
{
}
}
}
NinjectDependencyResolver:
namespace WebUI.Infrastructure
{
public class NinjectDependencyResolver : IDependencyResolver
{
IKernel kernel;
public NinjectDependencyResolver(IKernel kernelParam)
{
kernel = kernelParam;
AddBindings();
}
public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
private void AddBindings()
{
kernel.Bind<IInterface1>().To<Class1>();
kernel.Bind<IInterface2>().To<Class2>();
kernel.Bind<SingletonClass>().To<SingletonClass>().InSingletonScope();
}
}
}
As far as I understand this code will help to return the same instance of SigletonClass:
kernel.Bind<SingletonClass>().To<SingletonClass>().InSingletonScope();
Service in App_Start:
namespace WebUI.App_Start
{
public class OperationManagerService
{
private IInterface1 _iInterface1;
private IInterface2 _iInterface2;
static OperationManagerService() //static constructor cannot have parameters
{
_iInterface1 = //how to initialize
_iInterface2 = //interfaces here?
}
public static void RegisterService()
{
new SingletonClass(_iInterface1, _iInterface2);
}
}
}
Register service in Application_Start (Global.asax.cs):
namespace WebUI
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
OperationManagerService.RegisterService();
}
}
}
UPDATE:
I must admit that I'm able to initialize dependencies like this, but then I can only use the OperationManagerService class in controller. Not in Application_Start!
static OperationManagerService(IInterface1 iInterface1, IInterface2 iInterface2)
{
_iInterface1 = iInterface1;
_iInterface2 = iInterface2;
}
This leads me to thought that I can't use injection with Ninject in Application_Start. If it's true, then where is the right place to create a class that should load at startup?
You are trying to intermix the Singleton pattern with Ninject's Singleton Scope, which confuses who is trying to construct what when. Don't use the old the Singleton pattern when trying to use DI. Half of the point of DI is to manage the lifetime (scope) of the objects it contains. You do this by specifying .InSingletonScope() as you have done.
Now, onto your question of injecting dependencies into a startup feature: you will need to allow Ninject to construct the OperationManagerService in order to have the dependencies provided by Ninject. To do this, register it in Singleton scope, as you did with SingletonClass. The first time it is requested from the Ninject container, it will be constructed and injected with the necessary parameters. Singleton scope only tells Ninject to only ever construct one instance.
However, it seems that you would like it to be constructed during startup? If this is a requirement, something will need to ask for it. The simplest solution would be to get it after binding it:
private void AddBindings()
{
kernel.Bind<IInterface1>().To<Class1>();
kernel.Bind<IInterface2>().To<Class2>();
kernel.Bind<SingletonClass>().ToSelf().InSingletonScope();
kernel.Bind<OperationManagerService>().ToSelf().InSingletonScope();
kernel.Get<OperationManagerService>(); // activate
}
If you find yourself doing this alot, I have used a simple "auto-start" pattern:
public interface IAutoStart()
{
void Start();
}
public class SomeClassThatStarts : IAutoStart
{
public void Start()
{
Console.Log("Starting!");
}
}
public class AutoStartModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
foreach(var starter in Kernel.GetAll<IAutoStart>())
{
starter.Start();
}
}
}
Register the AutoStartModule last in your Kernel, and any IAutoStart will be loaded with any dependencies and started.

Dependency Injection Container - How to keep available to

When creating an application with Dependency Injection and it utilizes a framework for Dependency Injection such as Unity (or Ninject).
How do you initialize registering the interfaces to the container at the beginning all together and keep them available for the application to use throughout its running lifecycle of the application?
Do you need to pass the DI Container to each method that may utilize dependency injection, or is there some way to make the container globally accessible so that you can register them all together in the beginning and access them throughout running the application without having to continually pass them, and be able to utilize them when ever needed?
Environment: Visual Studio 2015, C#, Microsoft Unity (for DI Container)
Example Code
static void Main(string[] args)
{
// Make Unity resolve the interface, providing an instance
// of TrivialPursuit class
var diContainer = new UnityContainer();
diContainer.RegisterType<IGame, TrivialPursuit>();
var gameInstance = diContainer.Resolve<IGame>();
var xotherClass = new AnotherClass();
xotherClass.TestOtherClassOtherMethod();
}
------ Another class without context of the Dependency Injection Class ------
public void TestOtherClassOtherMethod()
{
IGame gameInstance = -- -Container is Not available to resolve from in this class ---
}
Reason: I don't want to need to pass every possible type that I may need later on to each class I load up, I will just want to use the instances when I need them. The more deeper I get into classes, later as the application becomes more complex, I won't want to pass down instances for each type up from the Main() method to each class.
A Dependency Injection (DI) container is just that. A framework for facilitating DI. You don't pass the container around in order to resolve instances of objects. You just request the type you need in your classes constructor and the DI framework will inject the appropriate dependency.
Mark Seemann has written a good book on dependency injection that I would recommend.
You register everything that'll need to be resolved with the container in the composition root. That is to say when your program starts up is when everything should be registered.
Let's say we have the following code:
public class MyClass
{
public Run()
{
var dependency = new Dependency1();
dependency.DoSomething();
}
}
public class Dependency1
{
public void DoSomething()
{
var dependency = new Dependency2();
dependeny.DoSomethingElse();
}
}
public class Dependency2
{
public void DoSomethingElse()
{
}
}
This gives us the above dependency chain: MyClass -> Dependency1 -> Dependency2.
The first thing we should do is refactor the classes to take their dependencies through their constructor and rely on interfaces rather than concretions. We can't inject dependencies unless there is a place to inject them (constructor, property, etc).
Here is the refactored code:
public interface IMyClass
{
void Run();
}
public interface IDependency1
{
void DoSomething();
}
public interface IDependency2
{
void DoSomethingElse();
}
public class MyClass : IMyClass
{
public readonly IDependency1 dep;
public MyClass(IDependency1 dep)
{
this.dep = dep;
}
public void Run()
{
this.dep.DoSomething();
}
}
public class Dependency1 : IDependency1
{
public readonly IDependency2 dep;
public MyClass(IDependency2 dep)
{
this.dep = dep;
}
public void DoSomething()
{
this.dep.DoSomethingElse();
}
}
public class Dependency2 : IDependency2
{
public void DoSomethingElse()
{
}
}
You'll notice the classes now all take their dependencies through their constructors and do not new up anything. Classes should only take in dependencies that they actually need. For example, MyClass does not NEED a Dependency2 so it doesn't ask for one. It only asks for a Dependency1 because that's all it needs. Dependency1 NEEDS Dependency2, not MyClass.
Now to wire it all up WITHOUT a container we would just new it all up in the composition root:
void Main()
{
var myClass = new MyClass(new Dependency1(new Dependency2()));
}
You can see how that could get cumbersom if we had tons of classes and depdencies. That's why we use a container. It handles all the depdency graph for us. With a container we'd rewrite it as follows:
void Main()
{
// the order of our registration does not matter.
var container = new Container();
container.Register<IDependency1>.For<Dependency1>();
container.Register<IDependency2>.For<Dependency2>();
container.Register<IMyClass>.For<MyClass>();
// then we request our first object like in the first example (MyClass);
var myClass = container.Resolve<IMyClass>();
myClass.Run();
}
In the second example the container will handle wiring up all the dependencies. So we never need to pass Depedency2 to MyClass and then to Depedency1. We only need to request it in Dependency1 and the container will wire it up for us like in the first example.
So in your example we would rewrite it like so:
static void Main(string[] args)
{
var game = new UnityContainer();
game.RegisterType<IGame, TrivialPursuit>();
game.RegisterType<IAnotherClass, AnotherClass>();
game.RegisterType<IYetAnotherClass, YetAnotherClass>();
var gameInstance = game.Resolve<IGame>();
// you'll need to perform some action on gameInstance now, like gameInstance.RunGame() or whatever.
}
public class Game : IGame
{
public Game(IAnotherClass anotherClass)
{
}
}
public class AnotherClass : IAnotherClass
{
public AnotherClass(IYetAnotherClass yetAnotherClass)
{
}
}
public class YetAnotherClass : IYetAnotherClass {}
In these cases there is no need to pass the container around. You register your dependencies with the container then request them in your classes constructors. If you wish to use the container in the class WITHOUT requesting it through the constructor then you are not doing DI you are just using the container as a singleton service locator. Something that should generally be avoided.
Container as a Service Locator
This should be generally avoided but if you want to use the container as a service locator you have two options:
1) Pass the container into your classes that need it through the constructor.
You can use the above examples for wiring your classes up for DI. But instead of requesting a dependency like IDependency in the constructor you just pass the container.
public class Game : IGame
{
public Game(IContainer container)
{
var blah = container.Resolve<IBlah>();
}
}
2) Request your container through a static class:
public static class ServiceLocator
{
private static IContainer container;
public static IContainer Container
{
get
{
if (container == null)
{
container = new Container();
}
return container;
}
}
}
Register everything as normal in your composition root using the ServiceLocator class. Then to use:
public class MyClass
{
public void DoSomething()
{
var blah = ServiceLocator.Container.Resolve<IBlah>();
}
}

How to inject instance with [Dependency] attribute using Unity?

I am using Unity for dependency injection in ASP.NET C#.
Normally I would inject dependencies in the constructor, like:
class MyClass
{
private readonly ISomething _something;
public MyClass(ISomething something)
{
_something = something;
}
public MyMethod()
{
// _something is instantiated as expected
}
}
where the dependency has been configured as:
container.RegisterType<ISomething, Something>();
That's all great.
But now I need to do an injection without the use a constructor. So I read that I can use the dependency attribute [Dependency] for this purpose.
class MyClass
{
[Dependency]
private ISomething _something { get; set; }
public MyMethod()
{
// _something appears to be null
}
}
But for some reason _something appears to be null.
What am I missing?
SOLUTION:
See the accepted answer over here, which shows how to create a factory to generate the injected instance:
How to resolve dependency in static class with Unity?
Worked for me!
You are trying to inject into a private property. This is not possible.
And personally, I suggest you stick to constructor injections to prevent locking yourself into a specific Dependency Injection framework.

Pass parameter when initialising Dependency Injection in ASP.NET core

I have a simple class which looks like this:
public class TestClass1
{
private string testString = "Should be set by DI";
public TestClass1(string testString)
{
this.testString = testString;
}
public string GetData()
{
return testString + DateTime.Now;
}
}
I want to inject it using the build-in DI in a simple ASP.NET core web app, but with the "testString" parameter set when initialising the Dependency Injection.
I've tried setting the following in startup.cs but it fails at runtime because TestClass1 doesn't have a parameterless constructor:
services.AddScoped(provider => new TestClass1("Success!"));
I suspect you just missed the cruical part of the code and your usage of the DI is just plain wrong, not the registration.
public class MyController
{
private readonly MyClass myClass;
public MyController()
{
// This doesn't work and do not involve DI at all
// It will fail because MyClass has no parameterles constructor
this.myClass = new MyClass();
}
}
The above won't work, because DI is no compiler magic that let you magically inject dependencies when calling new on the type.
public class MyController
{
private readonly MyClass myClass;
public MyController(MyClass myClass)
{
// This should work, because the IoC/DI Container creates the instance
// and pass it into the controller
this.myClass = myClass;
}
}
When you use DI/IoC you let the constructor generate and instantiate the objects, hence you never call new in your service classes. Just tell in the constructor that you need an instance of some type or it's interface.
Edit:
This used to work in previous versions (betas) of ASP.NET Core. Should still work, but limited to parameters:
public class MyController
{
public IActionResult Index([FromServices]MyClass myClass)
{
}
}

Using property injection instead of constructor injection

Long story short, I'm trying to use ELMAH with MVC 2 and Ninject, and I need to use parameterless constructors. I created an initial post about it here: Using a parameterless controller constructor with Ninject?
I was advised to use property injection instead of constructor injection. So I moved from this:
public class DepartmentsController : Controller
{
private IDepartmentsRepository departmentsRepository;
public DepartmentsController(IDepartmentsRepository departmentsRepository)
{
this.departmentsRepository = departmentsRepository;
}
...
}
to this:
public class DepartmentsController : Controller
{
private IDepartmentsRepository _departmentsRepository;
[Inject]
public IDepartmentsRepository DepartmentsRepository
{
get { return _departmentsRepository; }
set { _departmentsRepository = value; }
}
...
}
But in my other controller functions, whether I try to access DepartmentsRepository or _departmentsRepository, I get an object reference not set to an instance of an object error when I try to access it.
Is there something else I need to do here?
I had a similar problem. Have a look at my questions: Using Ninject with Membership.Provider.
Basically when you initialise DepartmentsController you need to injectthis (i.e. your departments controller into your Ninject kernal. So its something like:
public class DepartmentsController : Controller
{
private IDepartmentsRepository _departmentsRepository;
[Inject]
public IDepartmentsRepository DepartmentsRepository
{
get { return _departmentsRepository; }
set { _departmentsRepository = value; }
}
public DepartmentsController()
{
NinjectHelper.Kernel.Inject(this);
}
}
Where NinjectHelper in this case gets the current Ninject Kernel.
Try something like this:
Global.asax.cs
protected void Application_Start()
{
DependencyResolver.SetResolver(
new MyDependencyResolver(
new StandardKernel(
new MyModule())));
//...
}
MyDependencyResolver.cs
public class MyDependencyResolver : IDependencyResolver
{
private IKernel kernel;
public MyDependencyResolver(IKernel kernel)
{
this.kernel = kernel;
}
public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
}
MyModule.cs
public class MyModule : NinjectModule
{
public override void Load()
{
Bind<IDepartmentsRepository>().To<DepartmentsRepository>();
}
}
There could be 2 reasons for object reference not set exception.
1) Ninject does not know how to Bind IDepartmentsRepository to a concrete implementation of DepartmentsRepository ( I doubt that is the case though )
2) If you are trying to access DepartmentsRepository property in your controller's constructor, it will throw the exception (since Ninject is only able to inject Property Dependencies after the object is constructed).
Hope that helps.
As Daniel T. in the above comment posted, you should check out Ninject.Web.Mvc. If you use the NinjectHttpApplication in that project, it will autowire everything for you, so that when the NinjectControllerFactory constructs a new controller, it will call Inject() for you to fill the property injections.
An observation for anyone arriving here having problems "Using property injection instead of constructor injection" with Ninject even if not specifically with MVC Controllers.
Ninject will only identify the [Inject] attribute on a property and perform the property injection on classes that are being brought to life as part of a Ninject chain of DI.
If you are creating the object like this
var myObj = new MyObj();
Ninject doesn't know about the class instantiation and so won't know to perform any injection.
In the MVC world you can use
var emailer = DependencyResolver.Current.GetService<IEmailer>();

Categories

Resources