Bạn có thể sử dụng chức năng tiêm xây dựng tự động bằng cách thay thế mặc định PageHandlerFactory
bằng tùy chỉnh. Bằng cách này bạn có thể sử dụng một constructor quá tải để tải các phụ thuộc. Trang của bạn có thể trông như thế này:
public partial class HomePage : System.Web.UI.Page
{
private readonly IDependency dependency;
public HomePage(IDependency dependency)
{
this.dependency = dependency;
}
// Do note this protected ctor. You need it for this to work.
protected HomePage() { }
}
Cấu hình tùy chỉnh mà PageHandlerFactory
thể được thực hiện trong web.config như sau:
<?xml version="1.0"?>
<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="*.aspx"
type="YourApp.CustomPageHandlerFactory, YourApp"/>
</httpHandlers>
</system.web>
</configuration>
CustomPageHandlerFactory
của bạn có thể trông như thế này:
public class CustomPageHandlerFactory : PageHandlerFactory
{
private static object GetInstance(Type type)
{
// TODO: Get instance using your favorite DI library.
// for instance using the Common Service Locator:
return Microsoft.Practices.ServiceLocation
.ServiceLocator.Current.GetInstance(type);
}
public override IHttpHandler GetHandler(HttpContext cxt,
string type, string vPath, string path)
{
var page = base.GetHandler(cxt, type, vPath, path);
if (page != null)
{
// Magic happens here ;-)
InjectDependencies(page);
}
return page;
}
private static void InjectDependencies(object page)
{
Type pageType = page.GetType().BaseType;
var ctor = GetInjectableCtor(pageType);
if (ctor != null)
{
object[] arguments = (
from parameter in ctor.GetParameters()
select GetInstance(parameter.ParameterType)
.ToArray();
ctor.Invoke(page, arguments);
}
}
private static ConstructorInfo GetInjectableCtor(
Type type)
{
var overloadedPublicConstructors = (
from constructor in type.GetConstructors()
where constructor.GetParameters().Length > 0
select constructor).ToArray();
if (overloadedPublicConstructors.Length == 0)
{
return null;
}
if (overloadedPublicConstructors.Length == 1)
{
return overloadedPublicConstructors[0];
}
throw new Exception(string.Format(
"The type {0} has multiple public " +
"ctors and can't be initialized.", type));
}
}
Nhược điểm là điều này chỉ hoạt động khi chạy bên bạn trong Full Trust. Bạn có thể đọc thêm về nó here. Nhưng lưu ý rằng việc phát triển các ứng dụng ASP.NET trong một phần tin cậy seems a lost cause.
Xin chào Steven, tôi có một cái gì đó như thế này được thực hiện trong dự án của tôi và nó hoạt động thực sự tốt. Nhưng tôi đang đối mặt với một vấn đề bây giờ. Nó được mô tả ở đây "http://stackoverflow.com/questions/15692499/page-routing-in-asp-net-4-0-extensionless-url-versus-pagehandlerfactory-asp". Bạn có thể vui lòng xem và có thể chia sẻ một số ý kiến? –
Castle Windsor. Nevermind, tôi đã giải quyết nó bằng cách giải quyết từ Boostrapper trong các trang. Nó không phải là mát mẻ, nhưng hey, nó làm việc và vẫn có vẻ tốt. –
Tôi tìm thấy bài viết tuyệt vời này http://www.codemag.com/Article/1210031 (Tôi nghĩ rằng được liên kết từ một câu trả lời SO khác, nhưng bây giờ tôi không thể tìm thấy cái nào) bao gồm mã ví dụ khác liên quan đến giải pháp trên và Ngoài ra, thật thú vị, cho thấy cách Microsoft Extensibility Framework (MEF) có thể giúp bạn giải quyết vấn đề này và các vấn đề tiêm phụ thuộc tương tự theo cách rất hữu ích và không chuẩn. –