Ответ 1
Из-за того, как разработан 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 framework создать для нас этот тип. Путь к этому заключается в том, чтобы позволить ASP.NET создать этот тип для нас и вызывать конструктор нестандартного класса базового класса _Default
для этого существующего экземпляра. Поскольку этот экземпляр уже существует, мы должны сделать это с помощью рефлексии, и это не сработает при выполнении частичного доверия.
Кроме того, это работает для классов страниц, но не для пользовательских элементов управления на странице. Генератор кода ASP.NET сообщает о том, что эти элементы управления со своим конструктором по умолчанию во время процесса иерархии управления создают процесс. Если вы хотите, чтобы это сработало для них, вам понадобится ваш PageHandlerFactory
для привязки к событию PreInit
для этих элементов управления, потому что за время, когда был создан класс страницы, связанные элементы управления и пользовательские элементы управления еще не созданы. Однако, чтобы зарегистрировать событие PreInit
на них, вам нужно найти эти элементы управления в классе страницы, и снова нам нужно задуматься над классом страницы. Поскольку элементы управления хранятся в непубличных экземплярах, снова это не будет работать в частичном доверии.
Независимо от того, является ли это проблемой ваше приложение не может работать в частичном доверии, зависит от вас, но поскольку модель безопасности .NET 4 значительно упрощена, очень просто запустить веб-приложения в частичном доверии, и это это то, к чему я стремлюсь.
TL;DR; Поэтому в заключение можно сделать это (см., Например, этот пример), но из-за ограничений ASP.NET Web Forms, вам нужно полностью доверять, чтобы заставить его работать.
ОБНОВЛЕНИЕ Microsoft устарела частичное доверие для ASP.NET, начиная с NET 4.0 (читайте здесь). Таким образом, с этой точки зрения, избегать полного доверия может быть не так полезно (в любом случае вам это понадобится).