问题
Nearly all of the Ninject examples I've seen explain how to use it with ASP.NET MVC, which will automatically inject dependencies into controllers. How would I use Ninject manually though? Let's say I have a custom ActionResult:
public class JsonResult : ActionResult
{
[Inject] public ISerializer Serializer { get; set; }
public JsonResult(object objectToSerialize)
{
// do something here
}
// more code that uses Serializer
}
Then in my controller, I'm using JsonResult
in a method like this:
public ActionResult Get(int id)
{
var someObject = repo.GetObject(id);
return new JsonResult(someObject);
}
As you can see, I'm instantiating the object myself, which sidesteps Ninject's injection, and Serializer
will be null. However, doing it the following way doesn't seem quite right to me:
public ActionResult Get(int id)
{
var someObject = repo.GetObject(id);
return IoC.Kernel.Get<JsonResult>(someObject);
}
Because now there's not only a dependency on Ninject in the controller, but I also have to expose the Ninject kernel in a static class/singleton and ensure that objects that rely on injection are only created via kernel.
Is there a way to somehow configure Ninject to inject the dependency without relying on exposing the kernel? I'd like to be able to use the new
keyword if at all possible.
回答1:
Use a factory that gets the kernel injected: E.g.
public class ResultFactory : IResultFactory
{
public ResultFactory(IKernel kernel)
{
this.kernel = kernel;
}
public JsonResult CreateJsonResult(object obj)
{
var result = this.kernel.Get<JsonResult>();
result.ObjectToSerialize = obj;
return result;
}
}
Inject this factory into the controller and use it to create your action results.
回答2:
I think you should turn your JsonResult
inside out:
public class JsonResult : ActionResult
{
public ISerializer Serializer { get; private set; }
public object ObjectToSerialize { get; set; }
public JsonResult(ISerializer serializer)
{
this.Serializer = serializer;
}
// more code that uses Serializer
}
This way you can retrieve the JsonResult
with the container like this:
public ActionResult Get(int id)
{
var result = IoC.Kernel.Get<JsonResult>();
result.ObjectToSerialize = repo.GetObject(id);
return result;
}
Changing the signature of the JsonResult
also enables Ninject to create an instance automatically. Because of this you can let Ninject automatically inject it as dependency into your controller:
public MyController(JsonResult result)
{
this.result = result;
}
public ActionResult Get(int id)
{
this.result.ObjectToSerialize = repo.GetObject(id);
return this.result;
}
来源:https://stackoverflow.com/questions/4083352/how-do-i-use-ninject-with-actionresults-while-making-the-controller-ioc-framewor