MVC 5 Ninject - как правильно его инициализировать

204
13 декабря 2017, 20:41

Добрый день. Речь идет о нюгет пакете "MVC 5 Ninject", который не создает дополнительных классов, но при этом можно пользоваться, например, классом IKernel:

// GET: Clients
public ActionResult Index()
{
    /*
     Через абстракцию работаем с клиентами
     */
    IKernel ninjectKernel = new StandardKernel();
    ninjectKernel.Bind<IClientBaseRepo>().To<ClientBaseRepo>();
    IClientBaseRepo clientsObj = ninjectKernel.Get<ClientBaseRepo>();

    var client = clientsObj.GetClientList(); //new ClientBaseRepo().GetClientList();
    return View(client);
}

Собственно и вопрос: если я хочу в каждом Действии Контроллера производить манипуляции с данными, то мне каждый раз в каждом Действии надо писать подобное:

IKernel ninjectKernel = new StandardKernel();
        ninjectKernel.Bind<IClientBaseRepo>().To<ClientBaseRepo>(); 

или можно в одном определенном каком-то месте сделать инициализацию и привязки?

Я думал поместить инициализацию в какое-нибудь единственное место Global.asax, но добавить его в проект у меня не получилось, такого элемента просто нету в списке.

C# MVC 5.0

Спасибо

Answer 1

Постоянно вызывать методы вроде Get или Resolve у DI-контейнеров - это едва ли не худшее применение контейнеров которое можно придумать. Хуже только доставать один контейнер из другого.

Все внешние зависимости должны быть либо параметрами конструктора, либо публичными свойствами. Первый способ предпочтительнее, но второй тоже допустим, особенно для точек входа в ваш код (таких как контроллер в ASP.NET MVC).

Поэтому вам надо создать в контроллере свойство типа IClientBaseRepo и пометить его атрибутом [Inject].

Настраивать же Ninject нужно в одном месте, такое место называется Composition Root. Для веб-приложений Composition Root - это обработчик Application_Start в Global.asax.cs, там и создавайте StandardKernel.

А для того чтобы инъекции в контроллеры работали - используйте пакет Ninject.Web.Mvc

Answer 2

Данная настройка делается один раз в классе, унаследованном от NinjectModule:

public class RemoteNinjectModule : NinjectModule
{
    public override void Load()
    {
        Bind<IClientBaseRepo>().To<ClientBaseRepo>();            
    }
}

объявляете в главном методе статическую переменную вышеописанного класса:

public partial class App
{
    public static StandardKernel appKernel;
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        appKernel = new StandardKernel(new RemoteNinjectModule());
        var mainWindow = new MainWindow();
        mainWindow.Show();
    }
}

затем в приложении просто получаете экземпляр Вашего класса:

IClientBaseRepo repo = App.appKernel.Get<IClientBaseRepo >()
READ ALSO
Динамическое меню MVVM

Динамическое меню MVVM

Нужно создать меню, одна часть которого будет загружаться при запуске программы, а вторая часть будет статическаяКаким образом можно это...

273
C# .NET замена содержимого блока &lt;div&gt;

C# .NET замена содержимого блока <div>

К примеру у нас имеется divreklama ,а в нем картинка Как с помощью HttpListener или чего-то другого изменить содержимое div

211
Узнать URL до загрузки страницы C# WebDriver

Узнать URL до загрузки страницы C# WebDriver

Добрый деньВозникла следующая задачка: приложение на selenium должно узнавать url загружаемой страницы до ее загрузки, проверять, соответствует...

215
VS C# база данных mssql

VS C# база данных mssql

Как можно изменить путь подключения к бд, чтобы при переносе на другой комп заново не прописывать новый путь к базе данных? Чтобы без этого...

221