How do I use Ninject with ActionResults while making the controller IoC-framework-agnostic?

送分小仙女□ 提交于 2019-12-05 02:46:27

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!