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] или что-то еще, но вы уже потеряли в тот момент, потому что вы только что "раскрыли свои источники" контроллеру, что противоречит точке Инвертирования - вы можете просто пропустить Ninject IKernel к контроллеру.

  • В любом случае, в вашем случае 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);
    }
}
Другие вопросы по тегам