Из-за способа разработки ASP.NET классы Page
должны иметь конструктор по умолчанию.Когда вы хотите использовать инжектор конструктора, есть способ обойти это.Вы можете сделать конструктор по умолчанию защищенным и добавить один общедоступный конструктор, который принимает зависимости следующим образом:
public partial class _Default : System.Web.UI.Page
{
private IUserService service;
protected _Default()
{
}
public _Default(IUserService service)
{
this.service = service;
}
}
Это позволяет создать пользовательский PageHandlerFactory
и внедрить зависимости в конструкторе.
Так что это работает, но есть одна загвоздка.Класс _Default
, который вы определяете, не является фактическим классом, используемым ASP.NET.ASP.NET создает новый класс, который наследуется от _Default
.Этот новый класс строит иерархию элементов управления на основе разметки в файле .aspx.Этот класс выглядит примерно так:
public class ASPGeneratedDefault : _Default
{
public ASPGeneratedDefault() : base()
{
}
protected override void OnPreInit(object s, EventArgs e)
{
// Building up control hierarchy.
}
}
Как видите, пользовательский конструктор не был переопределен в ASPGeneratedDefault
ASP.NET.Из-за этого нет никакой возможности позволить платформе DI создать этот тип для нас.Обходной путь - позволить ASP.NET создать этот тип для нас и вызвать конструктор не по умолчанию базового класса _Default
для этого существующего экземпляра.Поскольку этот экземпляр уже существует, мы должны сделать это с отражением, и это не удастся выполнить при частичном доверии.
Кроме того, это работает для классов страницы, но не для пользовательских элементов управления на странице.Генератор кода ASP.NET сообщает эти элементы управления с помощью конструктора по умолчанию в процессе создания иерархии элементов управления.Если вы хотите, чтобы это работало для них, вам нужно, чтобы ваш пользовательский PageHandlerFactory
подключился к событию PreInit
этих элементов управления, потому что во время создания класса страницы соответствующие элементы управления и пользовательские элементы управления еще не созданы.Однако, чтобы зарегистрировать на них событие PreInit
, вам нужно найти эти элементы управления в классе страницы, и снова нам нужно подумать над классом страницы.Поскольку элементы управления хранятся в непубличных полях экземпляра, опять же, это не будет работать при частичном доверии.
Независимо от того, является ли это проблемой, ваше приложение не может быть запущено при частичном доверии, решать вам, но так какмодель безопасности .NET 4 значительно упрощена, очень легко запускать веб-приложения с частичным доверием, и я стараюсь это делать.
TLDR ;Таким образом, в заключение можно сделать это (см., Например, этот пример ), но из-за ограничений платформы ASP.NET Web Forms, вам нужно работать с полным доверием, чтобы получитьэто работает.
ОБНОВЛЕНИЕ Microsoft устарела частичное доверие для ASP.NET, начиная с NET 4.0 (читайте здесь ).Так что с этой точки зрения держаться подальше от полного доверия может быть не очень полезно (оно все равно понадобится).