[seasar-dotnet:718] S2ContainerのASP.NETでの利用について
Hiroki Inoue
[E-MAIL ADDRESS DELETED]
2007年 12月 28日 (金) 01:35:10 JST
初めまして、井上と申します。
初めてのDIコンテナとしてSeasar2を勉強中なのですが、ASP.NETでS2Containerを
利用するにあたり、2点ご教授いただきたいことがあります。
「http://s2container.net.seasar.org/ja/asp.html」に記述のある、リクエストの
自動バインディングとWebフォームに対してのDIです。
対象バージョンは最新の1.3.5です。
まず、リクエストの自動バインディングですが、HttpRequestをバインディングするには
コンポーネント中にプロパティ(SET)を定義するだけで自動バインディングされる、と
書かれていますが、手動はできても自動がうまくいきません。
試したプログラムは次のとおりです。言語はVB.NETです。
App_Data/sample.dicon(抜粋)
-----
<component
name="SampleLogic"
class="Sample.Web.Logic.SampleLogic"
instance="request"/>
-----
App_Code/SampleCode.vb
-----
Imports Microsoft.VisualBasic
Imports Seasar.Framework.Container
Namespace Sample.Web.Logic
Public Interface ISampleLogic
Function GetSampleValue() As String
End Interface
Public Class SampleLogic : Implements ISampleLogic
Private req As HttpRequest
Private con As IS2Container
Public WriteOnly Property Request() As HttpRequest
Set(ByVal value As HttpRequest)
req = value
End Set
End Property
Public WriteOnly Property Container() As IS2Container
Set(ByVal value As IS2Container)
con = value
End Set
End Property
Public Function GetSampleValue() As String _
Implements ISampleLogic.GetSampleValue
Return req.UserAgent
End Function
End Class
End Namespace
-----
Default.aspx.vb(抜粋)
-----
Protected Sub Page_Load( _
ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim c As IS2Container = SingletonS2ContainerFactory.Container()
Dim s As ISampleLogic = c.GetComponent(GetType(ISampleLogic))
Label1.Text = s.GetSampleValue()
End Sub
-----
「SampleLogic」というコンポーネントを定義して「Default.aspx」で使うのですが、
実行すると「SampleLogic」の「GetSampleValue()」の「req」で「NullReference
Exception」が起きます。確かに「req」のインスタンスは「Nothing」でした。
同じように定義してある「con」には「Seasar.Framework.Container.Impl.
S2ContainerImpl」のインスタンスが入っていました。
そこで、試しに「sample.dicon」で次のように手動バインディングするように
変更したら動作しました。
-----
<component
name="SampleLogic"
class="Sample.Web.Logic.SampleLogic"
instance="request">
<property name="Request">request</property>
<property name="Container">container</property>
</component>
-----
「container」には「Request」を持っているので「GetSampleValue()」で
「con.Request.UserAgent」としたり、極端な話バインディングしなくても
「HttpContext.Current」からとれるので別に困りはしない
のですが…。
自動バインディングのやり方が間違っているのでしょうか?
2つ目のWebフォームに対してのDIについてですが、コンポーネント定義はパスを
使って「instance="outer"」で定義すればよいようですが、うまくいきません…。
試したプログラムは上のものを変更して次のとおりです。
App_Data/sample.dicon(抜粋)
-----
<component name="/Default.aspx" instance="outer"/>
-----
Default.aspx.vb(抜粋)
-----
Private obj As ISampleLogic
Public WriteOnly Property SampleLogic() As ISampleLogic
Set(ByVal value As ISampleLogic)
obj = value
End Set
End Property
Protected Sub Page_Load( _
ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
SingletonS2ContainerFactory.Container(). _
InjectDependency(Me, "/Default.aspx")
Label1.Text = obj.GetSampleValue()
End Sub
-----
受け口としてのプロパティをWebフォームのクラスに用意し、「Page_Load」で
「InjectDependency」をしています。
「InjectDependency」は実行してもエラーなく通るのですが、「obj」にDIされて
いません。手動バインディングしようとしても「JScriptEvaluateRuntimeException」
が発生してうまくいきませんでした。
「outer」の扱い自体が間違っているのかと思い、「Dummy」というクラスを作成
して、それを「outer」のコンポーネントとして「InjectDependency」してみたの
ですが、これはうまくいきました。次のとおりです。
App_Data/sample.dicon(抜粋)
-----
<component
name="Dummy"
class="Sample.Web.Logic.Dummy"
instance="outer"/>
-----
Dummy.vb
-----
Imports Microsoft.VisualBasic
Imports Seasar.Framework.Container.Factory
Namespace Sample.Web.Logic
Public Interface IDummy
Function GetSampleValueByDummy() As String
End Interface
Public Class Dummy : Implements IDummy
Private obj As ISampleLogic
Public WriteOnly Property SampleLogic() As ISampleLogic
Set(ByVal value As ISampleLogic)
obj = value
End Set
End Property
Public Sub New()
SingletonS2ContainerFactory.Container(). _
InjectDependency(Me, "Dummy")
End Sub
Public Function GetSampleValueByDummy() As String _
Implements IDummy.GetSampleValueByDummy
Return obj.GetSampleValue()
End Function
End Class
End Namespace
-----
-----
Protected Sub Page_Load( _
ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim d As IDummy = New Dummy()
Label1.Text = d.GetSampleValueByDummy()
End Sub
-----
「/Default.aspx」コンポーネントに対しても、「Dummy」コンポーネント
に対しても、「outer」で同じように内部で「InjectDependency」している
つもりなのですが、前者は失敗、後者は成功です。
WebフォームへのDIに対する考え方が間違っているのでしょうか?
参考資料をいろいろ探してみたのですが、自力解決できませんでした。
初歩的な内容なのかもしれませんが、よろしくお願いします。
seasar-dotnet メーリングリストの案内