Как я могу использовать Ninject с ActionResults, делая контроллер независимым от IoC-framework? - PullRequest
3 голосов
/ 03 ноября 2010

Почти все примеры Ninject, которые я видел, объясняют, как использовать его с ASP.NET MVC, который автоматически вводит зависимости в контроллеры.Как бы я использовал Ninject вручную, хотя?Допустим, у меня есть пользовательский ActionResult:

public class JsonResult : ActionResult
{
    [Inject] public ISerializer Serializer { get; set; }

    public JsonResult(object objectToSerialize)
    {
        // do something here
    }

    // more code that uses Serializer
}

Затем в моем контроллере я использую JsonResult таким способом:

public ActionResult Get(int id)
{
    var someObject = repo.GetObject(id);
    return new JsonResult(someObject);
}

Как видите, яЯ сам создаю экземпляр объекта, который обходит инъекцию Ninject, и Serializer будет нулевым.Тем не менее, делать это следующим образом не кажется мне правильным:

public ActionResult Get(int id)
{
    var someObject = repo.GetObject(id);
    return IoC.Kernel.Get<JsonResult>(someObject);
}

Потому что теперь в контроллере есть не только зависимость от Ninject, но я также должен выставить ядро ​​Ninject в статическом состоянии.class / singleton и убедитесь, что объекты, основанные на внедрении, создаются только через ядро.

Есть ли способ каким-то образом настроить Ninject для внедрения зависимости, не полагаясь на раскрытие ядра?Я хотел бы иметь возможность использовать ключевое слово new, если это возможно.

Ответы [ 2 ]

12 голосов
/ 03 ноября 2010

Используйте фабрику, которая вводит ядро: Например,

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;
    }
}

Вставьте эту фабрику в контроллер и используйте ее для создания результатов ваших действий.

0 голосов
/ 03 ноября 2010

Я думаю, вы должны вывернуть JsonResult наизнанку:

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
}

Таким образом, вы можете получить JsonResult с таким контейнером:

public ActionResult Get(int id)
{
    var result = IoC.Kernel.Get<JsonResult>();

    result.ObjectToSerialize = repo.GetObject(id);

    return result;
}

Изменение подписи JsonResult также позволяет Ninject автоматически создавать экземпляр. По этой причине вы можете позволить Ninject автоматически внедрить его как зависимость в ваш контроллер:

public MyController(JsonResult result)
{
    this.result = result;
}

public ActionResult Get(int id)
{
    this.result.ObjectToSerialize = repo.GetObject(id);

    return this.result;
}
...