Ninject,ASP.NET和自定义控件

问题描述 投票:4回答:2

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

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

如果没有,我将继续扩展Ninject :)

asp.net webforms custom-controls ninject ioc-container
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 <[email protected]>
+// 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 <[email protected]>
+// 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);
+        }
+        /*----------------------------------------------------------------------------------------*/
+    }
+}

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集合。这可能会导致问题,因为此方法现在在生命周期的早期调用。
  • 它循环遍历所有控件,因此效率不高。
© www.soinside.com 2019 - 2024. All rights reserved.