Есть много примеров того, как он работал над приложением MVC. Как это делается в веб-формах?
Как я могу реализовать Ninject или DI в asp.net Web Forms?
Ответ 1
Ниже приведены шаги по использованию Ninject с WebForms.
Шаг 1 - Загрузки
Требуется две загрузки - 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
Глобальный класс должен получить от 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)
.
Единственная проблема, которую я обнаружил, - это инъекция объектов в User Controls. Хотя возможно создать собственный базовый UserControl с возможностями Ninject, я нашел, что быстрее добавить свойство в пользовательский элемент управления для требуемого объекта и установить свойство на странице контейнера. Я думаю, что поддержка UserControls из коробки находится в списке Ninject "to-do".
Добавление Ninject довольно простое, и это красноречивое решение IoC. Многим это нравится, потому что нет конфигурации Xml. Он имеет другие полезные "трюки", такие как превращение объектов в синглтоны с помощью синтаксиса Ninject - Bind<ILogger>().To<WebLogger>().InSingletonScope()
. Нет необходимости менять WebLogger на фактическую имплантацию Singleton, мне это нравится.
Ответ 2
Это стало легче с выпуском Ninject v3.0 (по состоянию на 4/12/2012). Инъекция реализуется через HttpModule, поэтому нет необходимости наследовать ваши страницы из пользовательской страницы /MasterPage. Вот шаги (и код) для быстрого всплеска.
- Создайте новый проект ASP.NET WebForms
- Используйте NuGet для добавления библиотеки Ninject.Web(которая также приведет к уничтожению библиотек Ninject.Web.Common и Ninject)
- Зарегистрируйте свои настраиваемые привязки в приложении App_Start/NinjectWebCommon.cs/RegisterServices
- Использование вставки атрибутов на ваших страницах
NinjectWebCommon/RegisterServices
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IAmAModel>().To<Model1>();
}
По умолчанию
public partial class _Default : System.Web.UI.Page
{
[Inject]
public IAmAModel Model { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
System.Diagnostics.Trace.WriteLine(Model.ExecuteOperation());
}
}
Site.Master
public partial class SiteMaster : System.Web.UI.MasterPage
{
[Inject]
public IAmAModel Model { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
System.Diagnostics.Trace.WriteLine("From master: "
+ Model.ExecuteOperation());
}
}
Модели
public interface IAmAModel
{
string ExecuteOperation();
}
public class Model1 : IAmAModel
{
public string ExecuteOperation()
{
return "I am a model 1";
}
}
public class Model2 : IAmAModel
{
public string ExecuteOperation()
{
return "I am a model 2";
}
}
Результаты из окна вывода
I am a model 1
From master: I am a model 1
Ответ 3
Я думаю, что вот шаги по реализации Ninject.Web в веб-формах ASP.NET.
- Внедрить NinjectHttpApplication в Global.asax. Для ядра передайте его, выполнив NinjectModule.
- В каждом событии загрузки страницы веб-форм позади кода реализуется Ninject.Web.PageBase. Добавьте класс экземпляра с фильтром [Inject] поверх него.
Для более подробного примера ниже приведены некоторые полезные ссылки, которые я нашел:
Ответ 4
Ответ здесь в настоящее время не работает из-за ошибки . Ниже приведена модифицированная версия шагов @Jason с использованием клиентского httpmodule для ввода на страницы и элементов управления без необходимости наследования из классов ninject.
- Создайте новый проект ASP.NET WebForms
- Используйте NuGet для добавления библиотеки Ninject.Web
- Зарегистрируйте свои настраиваемые привязки в приложении App_Start/NinjectWebCommon.cs/RegisterServices
- Добавить InjectPageModule и зарегистрироваться в NinjectWebCommon
- Использование вставки атрибутов на ваших страницах
InjectPageModule.cs
public class InjectPageModule : DisposableObject, IHttpModule
{
public InjectPageModule(Func<IKernel> lazyKernel)
{
this.lazyKernel = lazyKernel;
}
public void Init(HttpApplication context)
{
this.lazyKernel().Inject(context);
context.PreRequestHandlerExecute += OnPreRequestHandlerExecute;
}
private void OnPreRequestHandlerExecute(object sender, EventArgs e)
{
var currentPage = HttpContext.Current.Handler as Page;
if (currentPage != null)
{
currentPage.InitComplete += OnPageInitComplete;
}
}
private void OnPageInitComplete(object sender, EventArgs e)
{
var currentPage = (Page)sender;
this.lazyKernel().Inject(currentPage);
this.lazyKernel().Inject(currentPage.Master);
foreach (Control c in GetControlTree(currentPage))
{
this.lazyKernel().Inject(c);
}
}
private IEnumerable<Control> GetControlTree(Control root)
{
foreach (Control child in root.Controls)
{
yield return child;
foreach (Control c in GetControlTree(child))
{
yield return c;
}
}
}
private readonly Func<IKernel> lazyKernel;
}
NinjectWebCommon/RegisterServices
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IHttpModule>().To<InjectPageModule>();
kernel.Bind<IAmAModel>().To<Model1>();
}
По умолчанию
public partial class _Default : System.Web.UI.Page
{
[Inject]
public IAmAModel Model { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
System.Diagnostics.Trace.WriteLine(Model.ExecuteOperation());
}
}
Site.Master
public partial class SiteMaster : System.Web.UI.MasterPage
{
[Inject]
public IAmAModel Model { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
System.Diagnostics.Trace.WriteLine("From master: "
+ Model.ExecuteOperation());
}
}
Модели
public interface IAmAModel
{
string ExecuteOperation();
}
public class Model1 : IAmAModel
{
public string ExecuteOperation()
{
return "I am a model 1";
}
}
public class Model2 : IAmAModel
{
public string ExecuteOperation()
{
return "I am a model 2";
}
}
Результаты из окна вывода
I am a model 1
From master: I am a model 1
Ответ 5
Посмотрите на расширение Ninject.Web. Он обеспечивает базовую инфраструктуру https://github.com/ninject/ninject.web
Ответ 6
Проверьте книгу "Про ASP.NET MVC 2 Framework, второе издание" Стив Сандерсон (Apress). Автор использует Ninject для подключения к базе данных. Я думаю, вы можете использовать примеры и адаптировать их к вашим потребностям.