Ниже приведены инструкции по использованию Ninject с веб-формами.
Step1 - Загрузки
Требуется две загрузки - Ninject-2.0.0.0-release-net-3.5 и расширения WebForm Ninject.Web_1.0.0.0_With.log4net (существует NLog альтернатива).
В веб-приложении должны быть ссылки на следующие файлы: Ninject.dll, Ninject.Web.dll, Ninject.Extensions.Logging.dll и Ninject.Extensions.Logging.Log4net.dll.
Шаг 2 - Global.asax
Класс Global должен быть производным от Ninject.Web.NinjectHttpApplication
и реализовать CreateKernel()
, который создает контейнер:
using Ninject; using Ninject.Web;
namespace Company.Web {
public class Global : NinjectHttpApplication
protected override IKernel CreateKernel()
{
IKernel kernel = new StandardKernel(new YourWebModule());
return kernel;
}
Конструктор StandardKernel
занимает Module
.
Шаг 3 - Модуль
Модуль, в данном случае YourWebModule
, определяет все привязки, которые понадобятся веб-приложению:
using Ninject;
using Ninject.Web;
namespace Company.Web
{
public class YourWebModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
Bind<ICustomerRepository>().To<CustomerRepository>();
}
В этом примере, где бы ни указывался интерфейс ICustomerRepository
, будет использоваться бетон CustomerRepository
.
Шаг 4 - Страницы
После этого каждая страница должна наследоваться от Ninject.Web.PageBase
:
using Ninject;
using Ninject.Web;
namespace Company.Web
{
public partial class Default : PageBase
{
[Inject]
public ICustomerRepository CustomerRepo { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
Customer customer = CustomerRepo.GetCustomerFor(int customerID);
}
InjectAttribute -[Inject]
- сообщает Ninject о необходимости ввода ICustomerRepository
в свойство CustomerRepo.
Если у вас уже есть базовая страница, вам просто нужно получить базовую страницу для получения из Ninject.Web.PageBase.
Шаг 5 - Мастер-страницы
Неизбежно, у вас будут мастер-страницы, и для того, чтобы MasterPage мог получить доступ к внедренным объектам, вам нужно извлечь свою мастер-страницу из Ninject.Web.MasterPageBase
:
using Ninject;
using Ninject.Web;
namespace Company.Web
{
public partial class Site : MasterPageBase
{
#region Properties
[Inject]
public IInventoryRepository InventoryRepo { get; set; }
Шаг 6 - Методы статической веб-службы
Следующая проблема не заключалась в возможности внедрения в статические методы. У нас было несколько Ajax PageMethods, которые явно статичны, поэтому мне пришлось перенести методы в стандартный веб-сервис. Опять же, веб-сервис должен быть производным от класса Ninject - Ninject.Web.WebServiceBase
:
using Ninject;
using Ninject.Web;
namespace Company.Web.Services
{
[WebService(Namespace = "//tempuri.org/">http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class YourWebService : WebServiceBase
{
#region Properties
[Inject]
public ICountbackRepository CountbackRepo { get; set; }
#endregion
[WebMethod]
public Productivity GetProductivity(int userID)
{
CountbackService _countbackService =
new CountbackService(CountbackRepo, ListRepo, LoggerRepo);
В вашем JavaScript вам нужно ссылаться на стандартную службу - Company.Web.Services.YourWebService.GetProductivity(user, onSuccess)
, а не PageMethods.GetProductivity(user, onSuccess)
.
Единственная другая проблема, которую я обнаружил, - это введение объектов в элементы управления пользователя. Хотя можно создать собственный базовый UserControl с возможностями Ninject, я обнаружил, что быстрее добавить свойство в пользовательский элемент управления для требуемого объекта и задать свойство на странице контейнера. Я думаю, что поддержка UserControls из коробки находится в списке «дел» Ninject.
Добавление Ninject довольно просто и является красноречивым решением IoC. Многим это нравится, потому что нет конфигурации Xml. У него есть другие полезные «уловки», такие как превращение объектов в синглтоны только с синтаксисом Ninject - Bind<ILogger>().To<WebLogger>().InSingletonScope()
. Нет необходимости менять WebLogger на фактическую имплементацию Singleton, мне это нравится.