如何在 ASP.NET Web 窗体中使用依赖注入 [英] How to use Dependency Injection with ASP.NET Web Forms

查看:14
本文介绍了如何在 ASP.NET Web 窗体中使用依赖注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试找出一种方法,将依赖注入与 ASP.NET Web 窗体控件结合使用.

I am trying to work out a way to use dependency injection with ASP.NET Web Forms controls.

我有很多控件可以直接创建存储库,并使用它们来访问和绑定数据等.

I have got lots of controls that create repositories directly, and use those to access and bind to data etc.

我正在寻找一种模式,我可以在其中将存储库从外部 (IoC) 传递给控件,​​因此我的控件仍然不知道存储库的构造方式以及它们的来源等.

I am looking for a pattern where I can pass repositories to the controls externally (IoC), so my controls remain unaware of how repositories are constructed and where they come from etc.

我不希望我的控件依赖 IoC 容器,因此我只想能够使用构造函数或属性注入来构造控件.

I would prefer not to have a dependency on the IoC container from my controls, therefore I just want to be able to construct the controls with constructor or property injection.

(更复杂的是,这些控件在运行时由 CMS 构建并放置在页面上!)

(And just to complicate things, these controls are being constructed and placed on the page by a CMS at runtime!)

有什么想法吗?

推荐答案

2019 年更新:随着 Web Forms 4.7.2 的推出,现在对 DI 有了更好的支持.这使以下内容无效.请参阅:连接简单的注射器在 .NET 4.7.2 中的 WebForms

UPDATE 2019: With the introduction of Web Forms 4.7.2, there is now better support for DI. This invalidates the below. See: Wiring up Simple Injector in WebForms in .NET 4.7.2

您可以通过用自定义的替换默认的 PageHandlerFactory 来使用自动构造函数注入.这样您就可以使用重载的构造函数来加载依赖项.您的页面可能如下所示:

You can use automatic constructor injection by replacing the default PageHandlerFactory with a custom one. This way you can use an overloaded constructor to load the dependencies. Your page might look like this:

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 () { }
}

配置自定义 PageHandlerFactory 可以在 web.config 中完成,如下所示:

Configuring that custom PageHandlerFactory can be done in the web.config as follows:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <httpHandlers>
      <add verb="*" path="*.aspx"
        type="YourApp.CustomPageHandlerFactory, YourApp"/>
    </httpHandlers>
  </system.web>
</configuration>

您的 CustomPageHandlerFactory 可能如下所示:

Your CustomPageHandlerFactory can look like this:

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));
    }
}

缺点是这只在完全信任的情况下运行时才有效.您可以阅读有关它的更多信息此处.但请注意,在部分信任的情况下开发 ASP.NET 应用程序 似乎是失败的原因.

Downside is that this only works when running your side in Full Trust. You can read more about it here. But do note that developing ASP.NET applications in partial trust seems a lost cause.

这篇关于如何在 ASP.NET Web 窗体中使用依赖注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆