ASP.NET MVC и Ninject - результат действия с параметром интерфейса
Вроде как новичок в MVC, и вроде как новинка с Ninject. Играя вокруг...
Я определил ninject в своем приложении MVC следующим образом:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind(
x => x.FromThisAssembly()
.SelectAllClasses()
.BindAllInterfaces()
);
}
У меня есть контроллер с формой и этот ActionResult:
public ActionResult Index(IMember Member)
{
return View();
}
и он возвращает ошибку: "Не удается создать экземпляр интерфейса".
Теперь я понимаю, что интерфейсу может не понравиться, но разве Ninject не должен вводить туда настоящий класс? мне нужно положить в фактический класс? если это так, разве это не лишает смысла использование интерфейсов и создание приложений с потерянными чашечками?
Кстати, в моем файле Index.cshtml в качестве первой строки указано следующее:
@model IMember
Спасибо
2 ответа
Вы, кажется, путаете внедрение зависимости конструктора с параметрами метода действия, это не одно и то же.
В вашем случае вы, кажется, хотите, чтобы Ninject каким-то образом ввел конкретный
IMember
реализация всякий раз, когда клиент (браузер и т. д.) вызываетIndex
действие.Имейте в виду, что любые параметры, которые будут переданы в метод Action, будут исходить от клиента, а не от фреймворка, поэтому делать это не имеет смысла.
Я уверен, что есть способ, которым вы могли бы воспользоваться, например, чтобы украсить параметр
[Inject]
или что-то еще, но вы уже потеряли в тот момент, потому что вы только что "раскрыли свои источники" контроллеру, что противоречит точке Инвертирования - вы можете просто пропустить NinjectIKernel
к контроллеру.В любом случае, в вашем случае Ninject будет внедрять только в конструктор контроллера (при условии, что вы правильно его подключили), и в этом отношении ответ Дага здесь действительно правильный - если это
IMember
это какая-то зависимость контроллера, то вы должны внедрить ее в конструктор и сохранить в ней, например, для закрытого члена, чтобы впоследствии вы могли ссылаться на него из методов действия.Если
IMember
это не зависимость от контроллера, а просто привязанный к модели параметр, который вы хотите передать своему контроллеру, тогда Dependency Injection не является ответом - параметр должен исходить от вызывающей стороны.
Кроме того, может возникнуть другая проблема, даже если вы в конечном итоге используете инжектор конструктора. Привязка на основе соглашения, которую вы используете, требует, чтобы был один класс с именем Member
который реализует IMember
то есть, что имя класса отличается от имени интерфейса только отсутствием начального "I". Если это не относится к вашему классу, тогда привязка на основе соглашения не будет работать в любом случае, и вам нужно использовать что-то явное, например
kernel.Bind<IMember>.To<MyMemberImplementationClassName>();
Надеюсь, это поможет.
Ваш метод RegisterServices находится в файле NinjectWebCommon.cs, который находится в папке App_Start?
Вам также нужно будет передать объект Member в вид, подобный приведенному ниже:
public class HomeController : Controller
{
private IMember _member;
public HomeController(IMember member)
{
_member = member;
}
public ActionResult Index()
{
return View(_member);
}
}