4

現在、ASP.NET (MVC ではなく標準) を使用しており、IOC コンテナーとして Ninject を使用しています。

ページに依存関係を挿入するために既に使用していますが、カスタム コントロールに依存関係を挿入する方法があるかどうか疑問に思っていました。

そうでない場合は、Ninject の拡張を開始します :)

4

2 に答える 2

6

さて、Ninject を拡張して、Ninject.Framework.Web dll に 2 つのクラスを追加しました。

自分で追加することに興味がある人のためのパッチは次のとおりです。

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 が発生したときに既にページ上にあるコントロールに対してのみ機能します。プロセスの後半でコントロールを追加すると、ループは既に実行されており、依存関係は挿入されません。
  • Controls コレクションを要求するため、これは一部のコントロールで CreateChildControls() を呼び出します。このメソッドはライフサイクルのかなり早い段階で呼び出されるようになったため、問題が発生する可能性があります。
  • すべてのコントロールをループするため、あまり効率的ではありません。
于 2011-11-02T14:36:10.917 に答える