15

Vì vậy, tôi có một trang web biểu mẫu web kế thừa và đang nỗ lực để duy trì dễ dàng hơn. Nhét nó đi và viết lại nó không phải là một lựa chọn.Tại sao tất cả mọi người nói tiêm phụ thuộc trong ASP.NET webforms là khó khăn khi PageHandlerFactory và IHttpHandlerFactory tồn tại?

IoC rõ ràng là một trong những điều đầu tiên nó nhận được, nhưng điều này khiến tôi với mẫu dịch vụ định vị và hương vị xấu, và tự hỏi liệu nó có thể được thực hiện tốt hơn hay không.

Những người khác nhau mà tôi đã nói chuyện trực tuyến và cho tôi biết rằng tôi có thể thực hiện việc tiêm bất động sản bằng một HttpModule quét lớp Trang cho các thuộc tính được trang trí với thuộc tính Tiêm hoặc tương tự, nhưng có vẻ như một lần phản chiếu (được lưu trong bộ nhớ cache) , nhưng vẫn) trên mọi yêu cầu. Không hấp dẫn.

Vì vậy, tôi đã xem xét các tùy chọn khác và đã xem qua số System.Web.IHttpHandlerFactory, điều này đã xuất hiện trong khuôn khổ kể từ phiên bản v2. Người ta có thể loại bỏ trình xử lý * .aspx mặc định và thay thế bằng trình xử lý sử dụng tùy chỉnh, trong phần httpHandlers web.config.

Vì vậy, những người tôi đã nói chuyện không câm; Tôi nghĩ tôi sẽ hỏi ở đây. Có bất kỳ gotchas nào thay thế các biểu mẫu web PageHandlerFactory bằng việc triển khai dựa trên IoC không ...?

Dường như nó có cả một CreateHandler và phương pháp ReleaseHandler, vì vậy phong cách sống liên quan đến rò rỉ bộ nhớ từ container giữ một tham chiếu đến các thành phần tạo ra không phải là một vấn đề ...

Trả lời

27

Do cách ASP.NET được thiết kế, các lớp Page cần phải có một hàm tạo mặc định. Khi bạn muốn sử dụng tiêm constructor, có một cách xung quanh này. Bạn có thể làm cho các nhà xây dựng mặc định bảo vệ và thêm một constructor công cộng duy nhất có sự phụ thuộc như sau:

public partial class _Default : System.Web.UI.Page 
{ 
    private IUserService service; 

    protected _Default() 
    { 
    } 

    public _Default(IUserService service) 
    { 
     this.service = service; 
    } 
} 

này cho phép bạn tạo ra một tùy chỉnh PageHandlerFactory và bơm phụ thuộc vào các nhà xây dựng.

Vì vậy, tính năng này hoạt động nhưng có một điểm bắt. Lớp _Default bạn xác định không phải là lớp ASP.NET thực tế sử dụng. ASP.NET tạo ra một lớp mới kế thừa từ _Default. Lớp mới này xây dựng một hệ thống phân cấp điều khiển dựa trên đánh dấu trong tệp .aspx. Lớp này trông hơi giống như thế này:

public class ASPGeneratedDefault : _Default 
{ 
    public ASPGeneratedDefault() : base() 
    { 
    } 

    protected override void OnPreInit(object s, EventArgs e) 
    { 
      // Building up control hierarchy. 
    } 
} 

Như bạn thấy, hàm tạo tùy chỉnh không bị ghi đè trong ASPGeneratedDefault bởi ASP.NET. Bởi vì điều này không có cách nào để cho phép một khuôn khổ DI tạo ra kiểu này cho chúng ta. Cách này là để cho ASP.NET tạo kiểu này cho chúng ta và gọi hàm dựng không mặc định của lớp cơ sở _Default trên cá thể hiện có đó. Bởi vì trường hợp này đã tồn tại, chúng ta phải làm điều này với sự phản chiếu và điều này sẽ thất bại khi chạy trong phần tin cậy.

Bên cạnh đó, tính năng này hoạt động đối với các lớp trang, nhưng không áp dụng cho các điều khiển của người dùng trên trang. Bộ tạo mã của ASP.NET tin tức lên những điều khiển với hàm tạo mặc định của chúng trong quá trình xây dựng hệ thống phân cấp điều khiển. Khi bạn muốn điều này làm việc cho chúng, bạn cần tùy chỉnh PageHandlerFactory để móc vào sự kiện PreInit của các điều khiển đó, bởi vì trong thời gian lớp trang được tạo, các điều khiển liên quan và điều khiển người dùng chưa được tạo. Tuy nhiên, để đăng ký sự kiện PreInit trên chúng, bạn cần phải tìm các điều khiển đó trong lớp trang và một lần nữa chúng tôi cần phản ánh qua lớp trang. Bởi vì các điều khiển được lưu trữ trong các trường cá thể không công khai, một lần nữa điều này sẽ không hoạt động trong phần tin cậy một phần.

Cho dù đó có phải là vấn đề mà ứng dụng của bạn không thể chạy trong sự tin tưởng một phần không tùy thuộc vào bạn, nhưng vì mô hình bảo mật của .NET 4 đã được đơn giản hóa đáng kể, rất dễ dàng để chạy các ứng dụng web một phần đó là điều tôi cố gắng làm.

TLDR; Vì vậy, trong kết luận, nó có thể làm như vậy (xem ví dụ this example), nhưng vì những hạn chế của khuôn khổ ASP.NET Web Forms, bạn cần phải chạy trong sự tin tưởng đầy đủ để làm cho nó hoạt động.

Cập nhật Microsoft đã quá tin tưởng một phần cho ASP.NET bắt đầu bằng NET 4.0 (đọc here). Vì vậy, từ quan điểm đó, tránh xa sự tin cậy hoàn toàn có thể không hữu ích (bạn sẽ cần nó).

Các vấn đề liên quan