【问题标题】:Ioc and WebForms - How to inject properties in user controlsIoc 和 WebForms - 如何在用户控件中注入属性
【发布时间】:2014-12-16 14:52:30
【问题描述】:

我正在将 IoC 添加到已经存在的 Web 表单项目中,但在注入用户控件的依赖项时遇到了一些麻烦,尤其是母版页中的动态用户控件。

在母版页上,我加载了一些用户控件:

protected override void OnLoad(EventArgs e)
    {
        bool processComplete = false;
        var page = Page as BasePage;
        if (page != null && HttpContext.Current.User.Identity.IsAuthenticated)
            processComplete = page.processComplete ;

        var segments = this.Request.Url.Segments;
        Control bodyheader = null;
        if (processComplete )
        {
            if (segments.Count() > 1 && segments[1].StartsWith("evaluation", true, System.Globalization.CultureInfo.CurrentCulture))
                bodyheader = Page.LoadControl("~/Themes/HWP/HeaderNoSearch.ascx");
            else
                bodyheader = Page.LoadControl("~/Themes/HWP/Header.ascx");
        }
        else if (segments.Count() > 1 && segments[1].StartsWith("welcome", true, System.Globalization.CultureInfo.CurrentCulture))
        {
            bodyheader = Page.LoadControl("~/Themes/HWP/plainHeaderAuth.ascx");
        }
        else
        {
            bodyheader = Page.LoadControl("~/Themes/HWP/plainHeaderAuth.ascx");
        }
        plcBodyHeader.Controls.Add(bodyheader);

        Control bodyfooter = Page.LoadControl("~/Themes/HWP/Footer.ascx");
        plcBodyFooter.Controls.Add(bodyfooter);

        base.OnLoad(e);
    }

这些用户控件中的每一个都有一些依赖关系。我可以在每个用户控件中手动注入依赖项:

protected override void OnInit(EventArgs e)
{
    var cpa = (IContainerProviderAccessor)HttpContext.Current.ApplicationInstance;
    var cp = cpa.ContainerProvider;
    cp.RequestLifetime.InjectProperties(this);
    base.OnInit(e);
}

但这似乎违背了使用 IoC 的目的。 MasterPage -> Page -> UserControls 应该如何构建以允许 DI?以及如何在动态用户控件中注入属性?我应该使用构造函数注入吗?

我正在使用 Autofac,但我认为这个问题与 IoC 无关。

【问题讨论】:

    标签: asp.net webforms inversion-of-control autofac


    【解决方案1】:

    你在正确的轨道上。我通常创建一个继承自 UserControlBaseUserControl 类。然后从这个 BaseUserControl 类继承所有 UserControls

    将所有必需的依赖项放在该 BaseUserControl 类中。

    public class BaseUserControl : UserControl
    {
        public ISomeService SomeService { get; set; }
        public IOtherService OtherService { get; set; }
    
        public BaseUserControl()
        {
            var cpa = (IContainerProviderAccessor)
                HttpContext.Current.ApplicationInstance;
            var cp = cpa.ContainerProvider;
            cp.RequestLifetime.InjectProperties(this);
        }
    }
    

    你可能会觉得有点浪费,因为不是所有的用户控件都使用所有的依赖。

    Mark Seemann 在 .NET 中的 Dependency Injection 一书中指出,依赖注入速度非常快,而且从来都不是问题。如果你认为你的应用程序很慢,它会来自你代码的其他地方(而不是依赖注入)。

    如果你想使用构造函数注入,看看这个answer

    【讨论】:

    • 好的。所以在这种情况下,IoC 将进行实例化,但我仍然必须手动告诉它开始?我试试看……
    • manually tell it to get started 否。BaseUserControl 构造函数会自动将依赖项注入这些属性。
    • 不需要将属性放入基类。您只能在派生控件中创建必需的属性。注射会正常工作。
    • 上帝保佑你的回应。我一直在寻找解决方案 3 天。它工作完美。我在 BaseControl 类中添加了控件中使用的所有属性。这种方式更容易。我只有8个属性。再次感谢。我忘了告诉你:这个解决方案基于 Autofac IOC。我统一使用了相同的想法。 var 容器 = HttpContext.Current.Application.GetContainer(); container.BuildUp(this);
    猜你喜欢
    • 1970-01-01
    • 2012-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多