[seasar-dotnet:719] Re: S2ContainerのASP.NETでの利用について

Kazuya Sugimoto [E-MAIL ADDRESS DELETED]
2007年 12月 28日 (金) 09:49:44 JST


井上さん、こんにちは。

杉本です。

1点目ですが、S2Container.NETの不具合だと思われます。
申し訳ありません。

試しにRequestというプロパティの1文字目を小文字にしてrequestという
プロパティにして、自動バインディングされるか試してもらえないでしょうか?

2点目ですが、調査してみますので時間を下さい。


07/12/28 に Hiroki Inoue さんは書きました:
> 初めまして、井上と申します。
>
> 初めての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 mailing list
> [E-MAIL ADDRESS DELETED]
> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>


-- 
Kazuya Sugimoto
Microsoft MVP Visual Developer - Solutions Architect
http://d.hatena.ne.jp/sugimotokazuya/


seasar-dotnet メーリングリストの案内