4

我目前正在使用 ASP.NET(标准,而不是MVC)并且我使用 Ninject 作为我的 IOC 容器。

我已经在使用它将依赖项注入到我的页面中,但是,我想知道是否有办法将依赖项注入到我的自定义控件中?

如果没有,我将开始扩展 Ninject :)

4

2 回答 2

6

好的,所以我最终扩展了 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);
+        }
+        /*----------------------------------------------------------------------------------------*/
+    }
+}
于 2009-08-16T15:33:34.697 回答
1

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

界面为空:

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(),因为您请求 Controls 集合。这可能会导致问题,因为现在在生命周期的早期调用此方法。
  • 它循环遍历所有控件,因此效率不高。
于 2011-11-02T14:36:10.917 回答