Есть много примеров того, как это работало в приложении MVC. Как это делается в веб-формах?
Вот шаги по использованию 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
Класс 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, мне это нравится.
Это стало проще с выпуском Ninject v3.0 (от 12.04.2012). Внедрение осуществляется через HttpModule, поэтому нет необходимости наследовать ваши страницы от настраиваемой Page / MasterPage. Вот шаги (и код) для быстрого всплеска.
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
источник
NinjectWeb.cs
вApp_Start
. Ваш код для инициализации Ninject должен находиться в этом файле. Если он в отдельном файле (напримерNinjectWebCommon.cs
, не сработает). Это может произойти, если вы установите Ninject.Web позже, чем другие пакеты Ninject, использующие NuGet.Ответ здесь в настоящее время не работает из-за открытой ошибки . Вот модифицированная версия шагов @Jason с использованием клиентского httpmodule для внедрения в страницы и элементы управления без необходимости наследования от классов ninject.
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
источник
if (currentPage.Master!=null) { this.lazyKernel().Inject(currentPage.Master); }
Я думаю, вот шаги по реализации Ninject.Web в веб-формах ASP.NET.
Для более подробного примера ниже приведены некоторые полезные ссылки, которые я нашел:
1. http://joeandcode.net/post/Ninject-2-with-WebForms-35
2. http://davidhayden.com/blog/dave/archive/2008/06/20/NinjectDependencyInjectionASPNETWebPagesSample.aspx
источник
Взгляните на расширение Ninject.Web. Он предоставляет базовую инфраструктуру https://github.com/ninject/ninject.web
источник
Посмотрите книгу Стива Сандерсона (Apress) "Pro ASP.NET MVC 2 Framework, 2nd Edition". Автор использует Ninject для подключения к базе данных. Я думаю, вы можете использовать примеры и адаптировать их к своим потребностям.
источник
public IGoalsService_CRUD _context { get; set; }
Для объекта _context каким-то образом устанавливается значение null. Ниже приведены остальные настройки.
public partial class CreateGoal : Page { [Inject] public IGoalsService_CRUD _context { get; set; } }
Для глобального файла
protected override IKernel CreateKernel() { IKernel kernel = new StandardKernel(new Bindings()); return kernel; } public class Bindings : NinjectModule { public override void Load() { Bind<goalsetterEntities>().To<goalsetterEntities>(); Bind<IGoalsService_CRUD>().To<GoalsService_CRUD>(); } }
источник