代码之家  ›  专栏  ›  技术社区  ›  Sekhat

Ninject、ASP.NET和自定义控件

  •  4
  • Sekhat  · 技术社区  · 15 年前

    我目前正在使用ASP.NET(标准, MVC)我使用ninject作为我的IOC容器。

    我已经在使用它将依赖项注入我的页面,但是,我想知道是否有一种方法可以将依赖项注入我的自定义控件?

    如果没有,我将继续进行扩展ninject:)

    2 回复  |  直到 7 年前
        1
  •  6
  •   Sekhat    7 年前

    好吧,我最后扩展了ninject,并向ninject.framework.web dll添加了两个类。

    以下是任何有兴趣自己添加它的人的补丁:

    Index: src/Framework/Web/Ninject.Framework.Web.csproj
    ===================================================================
    --- src/Framework/Web/Ninject.Framework.Web.csproj  (revision 158)
    +++ src/Framework/Web/Ninject.Framework.Web.csproj  (working copy)
    @@ -2,7 +2,7 @@
       <PropertyGroup>
         <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
         <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    -    <ProductVersion>9.0.21022</ProductVersion>
    +    <ProductVersion>9.0.30729</ProductVersion>
         <SchemaVersion>2.0</SchemaVersion>
         <ProjectGuid>{C46075DB-A0FB-466B-BA76-C093227FA9C7}</ProjectGuid>
         <OutputType>Library</OutputType>
    @@ -42,17 +42,24 @@
         <Reference Include="System.Core">
           <RequiredTargetFramework>3.5</RequiredTargetFramework>
         </Reference>
    +    <Reference Include="System.Data" />
    +    <Reference Include="System.Drawing" />
         <Reference Include="System.Web" />
         <Reference Include="System.Web.Services" />
    +    <Reference Include="System.Xml" />
       </ItemGroup>
       <ItemGroup>
         <Compile Include="..\..\GlobalAssemblyInfo.cs">
           <Link>Properties\GlobalAssemblyInfo.cs</Link>
         </Compile>
    +    <Compile Include="WebControlBase.cs" />
         <Compile Include="NinjectHttpApplication.cs" />
         <Compile Include="HttpHandlerBase.cs">
         </Compile>
         <Compile Include="NinjectHttpModule.cs" />
    +    <Compile Include="UserControlBase.cs">
    +      <SubType>ASPXCodeBehind</SubType>
    +    </Compile>
         <Compile Include="WebServiceBase.cs">
           <SubType>Component</SubType>
         </Compile>
    Index: src/Framework/Web/UserControlBase.cs
    ===================================================================
    --- src/Framework/Web/UserControlBase.cs    (revision 0)
    +++ src/Framework/Web/UserControlBase.cs    (revision 0)
    @@ -0,0 +1,65 @@
    +#region License
    +//
    +// Author: Nate Kohari <nkohari@gmail.com>
    +// Copyright (c) 2007-2008, Enkari, Ltd.
    +//
    +// Licensed under the Apache License, Version 2.0 (the "License");
    +// you may not use this file except in compliance with the License.
    +// You may obtain a copy of the License at
    +//
    +//   http://www.apache.org/licenses/LICENSE-2.0
    +//
    +// Unless required by applicable law or agreed to in writing, software
    +// distributed under the License is distributed on an "AS IS" BASIS,
    +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +// See the License for the specific language governing permissions and
    +// limitations under the License.
    +//
    +#endregion
    +#region Using Directives
    +using System;
    +using Ninject.Core.Logging;
    +using Ninject.Core;
    +using System.Web.UI;
    +#endregion
    +
    +namespace Ninject.Framework.Web
    +{
    +    /// <summary>
    +    /// A <see cref="UserControl"/> that supports injection
    +    /// </summary>
    +    public class UserControlBase : UserControl
    +    {
    +        /*----------------------------------------------------------------------------------------*/
    +        private ILogger _logger;
    +        /*----------------------------------------------------------------------------------------*/
    +        /// <summary>
    +        /// Gets or sets the logger associated with the object.
    +        /// </summary>
    +        [Inject]
    +        public ILogger Logger
    +        {
    +            get { return _logger; }
    +            set { _logger = value; }
    +        }
    +        /*----------------------------------------------------------------------------------------*/
    +        /// <summary>
    +        /// Raises the <see cref="E:System.Web.UI.Control.Init"></see> event to initialize the page.
    +        /// </summary>
    +        /// <param name="e">An <see cref="T:System.EventArgs"></see> that contains the event data.</param>
    +        protected override void OnInit(EventArgs e)
    +        {
    +            base.OnInit(e);
    +            RequestActivation();  
    +        }
    +        /*----------------------------------------------------------------------------------------*/
    +        /// <summary>
    +        /// Asks the kernel to inject this instance.
    +        /// </summary>
    +        protected virtual void RequestActivation()
    +        {
    +            KernelContainer.Inject(this);
    +        }
    +        /*----------------------------------------------------------------------------------------*/
    +    }
    +}
    Index: src/Framework/Web/WebControlBase.cs
    ===================================================================
    --- src/Framework/Web/WebControlBase.cs (revision 0)
    +++ src/Framework/Web/WebControlBase.cs (revision 0)
    @@ -0,0 +1,65 @@
    +#region License
    +//
    +// Author: Nate Kohari <nkohari@gmail.com>
    +// Copyright (c) 2007-2008, Enkari, Ltd.
    +//
    +// Licensed under the Apache License, Version 2.0 (the "License");
    +// you may not use this file except in compliance with the License.
    +// You may obtain a copy of the License at
    +//
    +//   http://www.apache.org/licenses/LICENSE-2.0
    +//
    +// Unless required by applicable law or agreed to in writing, software
    +// distributed under the License is distributed on an "AS IS" BASIS,
    +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +// See the License for the specific language governing permissions and
    +// limitations under the License.
    +//
    +#endregion
    +#region Using Directives
    +using System;
    +using System.Web.UI.WebControls;
    +using Ninject.Core.Logging;
    +using Ninject.Core;
    +#endregion
    +
    +namespace Ninject.Framework.Web
    +{
    +    /// <summary>
    +    /// A <see cref="WebControl"/> that supports injection
    +    /// </summary>
    +    public class WebControlBase : WebControl
    +    {
    +        /*----------------------------------------------------------------------------------------*/
    +        ILogger _logger;
    +        /*----------------------------------------------------------------------------------------*/
    +        /// <summary>
    +        /// Gets or sets the logger associated with the object.
    +        /// </summary>
    +        [Inject]
    +        public ILogger Logger
    +        {
    +            get { return _logger; }
    +            set { _logger = value; }
    +        }
    +        /*----------------------------------------------------------------------------------------*/
    +        /// <summary>
    +        /// Raises the <see cref="E:System.Web.UI.Control.Init"></see> event to initialize the page.
    +        /// </summary>
    +        /// <param name="e">An <see cref="T:System.EventArgs"></see> that contains the event data.</param>
    +        protected override void OnInit(EventArgs e)
    +        {
    +            base.OnInit(e);
    +            RequestActivation();
    +        }
    +        /*----------------------------------------------------------------------------------------*/
    +        /// <summary>
    +        /// Asks the kernel to inject this instance
    +        /// </summary>
    +        protected virtual void RequestActivation()
    +        {
    +            KernelContainer.Inject(this);
    +        }
    +        /*----------------------------------------------------------------------------------------*/
    +    }
    +}
    
        2
  •  1
  •   Sjoerd    13 年前

    我通过循环访问页面上的所有控件并注入实现某些接口的控件来解决这个问题。

    接口为空:

    public interface INinjectControl { }
    

    我在pagebase和masterpagebase中添加了一个循环,用于注入实现此接口的所有控件:

    protected virtual void RequestActivation()
    {
        KernelContainer.Inject( this );
        InjectControls(this.Controls);
    }
    
    private void InjectControls(ControlCollection controls)
    {
        foreach (Control control in controls)
        {
            if (control is INinjectControl)
                KernelContainer.Inject(control);
            this.InjectControls(control.Controls);
        }
    }
    

    有一些缺点:

    • 这仅适用于已在页面上的控件,当 OnInIT火灾。如果稍后在进程中添加控件,则循环 已经运行,并且不会注入依赖项。
    • 这会在一些控件上调用CreateChildControls(),因为您请求控件集合。这可能导致问题,因为这个方法现在在生命周期的早期被调用。
    • 它循环通过所有控件,因此效率不高。