Как я могу использовать Ninject с ActionResults, делая контроллер независимым от IoC-framework?
Почти все примеры 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 в статическом классе / синглтоне и убедиться, что объекты, основанные на внедрении, создаются только через ядро.
Есть ли способ как-то настроить Ninject для внедрения зависимости, не полагаясь на раскрытие ядра? Я хотел бы иметь возможность использовать new
ключевое слово, если это вообще возможно.
2 ответа
Используйте фабрику, которая вводит ядро: Например,
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;
}
}
Вставьте эту фабрику в контроллер и используйте ее для создания результатов ваших действий.
Я думаю, что вы должны повернуть 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;
}