[seasar-dotnet:357] Re: S2Container.NET上でのInterceptorChainについて
Kazuya Sugimoto
sugimotokazuya @ gmail.com
2006年 10月 2日 (月) 01:34:49 JST
小谷さん、こんにちは。
杉本です。
ソースコードありがとうございます。
InterceptorChainを追加しましょう。
https://www.seasar.org/issues/browse/CONTAINERNET-46
小谷さんは、SVNにコミットできますので、直接追加して頂けますでしょうか?
# なにか分からないことがあれば、なんでも聞いて下さい。(^_^)
06/10/01 に kk<koya-tsuti2 @ u01.gate01.com> さんは書きました:
> 初めまして。
> 小谷と申します。
> いつもお世話になっております。
>
> 表題の件について要望があります。
> 現在S2Container(Java版)の方にのみ実装されている
> InterceptorChainの機能をS2Container.NETの方にも
> 移植していただけないでしょうか。
>
> 私の方でも、Java版のクラスを参考に以下の
> ソースコードを試しに書いてみました。
> ・Seasar.Framework.Aop.Interceptors.InterceptorChain
> ・Seasar.Framework.Aop.Impl.NestedMethodInvocation
> ・Seasar.Framework.Util.ArrayUtil
> ・Seasar.Tests.Framework.Aop.Interceptors.InterceptorChainTest
>
> ○InterceptorChain ---------------------------------------
> using System;
> using System.Collections.Generic;
> using System.Text;
> using Seasar.Framework.Aop;
> using Seasar.Framework.Aop.Impl;
> using Seasar.Framework.Util;
>
> namespace Seasar.Framework.Aop.Interceptors
> {
> /// <summary>
> /// Interceptor collection
> /// </summary>
> public class InterceptorChain : AbstractInterceptor{
> private IMethodInterceptor[] interceptors = new
> IMethodInterceptor[0];
>
> /// <summary>
> /// Add an interceptor
> /// </summary>
> /// <param name="interceptor"></param>
> public void Add(IMethodInterceptor interceptor) {
> interceptors = (IMethodInterceptor[])ArrayUtil.Add(
> interceptors, interceptor);
> }
>
> /// <summary>
> /// Execute registed interceptors
> /// </summary>
> /// <param name="invocation"></param>
> /// <returns></returns>
> public override Object Invoke(IMethodInvocation invocation) {
> IMethodInvocation nestInvocation = new NestedMethodInvocation(
> (IS2MethodInvocation)invocation, interceptors);
> return nestInvocation.Proceed();
> }
> }
> }
> -------------------------------------------------------------
> ○NestedMethodInvocation -----------------------------------------
> using System;
> using System.Collections.Generic;
> using System.Text;
> using System.Reflection;
> using Seasar.Framework.Aop;
>
> namespace Seasar.Framework.Aop.Impl
> {
> /// <summary>
> /// NestedMethodInvocation
> /// </summary>
> public class NestedMethodInvocation : IS2MethodInvocation{
> private readonly IS2MethodInvocation parent;
>
> private readonly IMethodInterceptor[] interceptors;
> private int interceptorIndex = 0;
>
> public NestedMethodInvocation(IS2MethodInvocation parent,
> IMethodInterceptor[] interceptors) {
> this.parent = parent;
> this.interceptors = interceptors;
> }
>
> #region IS2MethodInvocationメンバ
>
> public Object[] Arguments {
> get {
> return parent.Arguments;
> }
> }
>
> public MethodBase Method {
> get {
> return parent.Method;
> }
> }
>
> public Object Target {
> get {
> return parent.Target;
> }
> }
>
> public Type TargetType {
> get {
> return parent.TargetType;
> }
> }
>
> public Object Proceed() {
> if (interceptorIndex < interceptors.Length ) {
> return interceptors[interceptorIndex++].Invoke(this);
> }
> return parent.Proceed();
> }
>
> public Object GetParameter(String name) {
> return parent.GetParameter(name);
> }
>
> #endregion
> }
> }
> -------------------------------------------------------
> ○ArrayUtil -------------------------------------------------
> using System;
> using System.Collections;
> using System.Text;
> using Seasar.Framework.Exceptions;
>
> namespace Seasar.Framework.Util
> {
> /// <summary>
> /// Utility of array
> /// </summary>
> public class ArrayUtil
> {
> private ArrayUtil() {
> }
>
> /// <summary>
> /// Add an item to array
> /// </summary>
> /// <param name="array"></param>
> /// <param name="obj"></param>
> /// <returns></returns>
> public static Object[] Add(Object[] array, Object obj){
> if( array == null ){
> throw new EmptyRuntimeException("array");
> }
> Object[] newArray = (Object[])Array.CreateInstance(
> array.GetType().GetElementType(), array.Length + 1);
> Array.Copy(array, 0, newArray, 0, array.Length);
> newArray[array.Length] =
> (Seasar.Framework.Aop.IMethodInterceptor)obj;
> return newArray;
> }
>
> /// <summary>
> /// Add an array to another array
> /// </summary>
> /// <param name="a"></param>
> /// <param name="b"></param>
> /// <returns></returns>
> public static Object[] Add(Object[] a, Object[] b) {
> if (a != null && b != null) {
> if (a.Length != 0 && b.Length != 0) {
> Object[] array = (Object[])Array.CreateInstance(
> a.GetType().GetElementType(), a.Length + b.Length);
> Array.Copy(a, 0, array, 0, a.Length);
> Array.Copy(b, 0, array, a.Length, b.Length);
> return array;
> } else if (b.Length == 0) {
> return a;
> } else {
> return b;
> }
> } else if (b == null) {
> return a;
> } else {
> return b;
> }
> }
>
> /// <summary>
> /// Index of array which is object
> /// </summary>
> /// <param name="array"></param>
> /// <param name="obj"></param>
> /// <returns></returns>
> public static int IndexOf(Object[] array, Object obj) {
> if (array != null) {
> return Array.IndexOf(array, obj);
> }
> return -1;
> }
>
> /// <summary>
> /// Index of array which is char
> /// </summary>
> /// <param name="array"></param>
> /// <param name="ch"></param>
> /// <returns></returns>
> public static int IndexOf(char[] array, char ch) {
> if (array != null) {
> for (int i = 0; i < array.Length; ++i) {
> char c = array[i];
> if (ch == c) {
> return i;
> }
> }
> }
> return -1;
> }
>
> /// <summary>
> /// Remove an object from array
> /// </summary>
> /// <param name="array"></param>
> /// <param name="obj"></param>
> /// <returns></returns>
> public static Object[] Remove(Object[] array, Object obj) {
> int index = IndexOf(array, obj);
> if (index < 0) {
> return array;
> }
> Object[] newArray = (Object[])Array.CreateInstance(
> array.GetType(), array.Length - 1);
> if (index > 0) {
> Array.Copy(array, 0, newArray, 0, index);
> }
> if (index < array.Length - 1) {
> Array.Copy(array, index + 1, newArray, index,
> newArray.Length - index);
> }
> return newArray;
> }
>
> public static bool IsEmpty(Object[] arrays) {
> return (arrays == null || arrays.Length == 0);
> }
>
> public static bool Contains(Object[] array, Object obj) {
> return (-1 < IndexOf(array, obj));
> }
>
> public static bool Contains(char[] array, char ch) {
> return (-1 < IndexOf(array, ch));
> }
> }
> }
> ----------------------------------------------------------------
> ○InterceptorChainTest -----------------------------------------
> using System;
> using System.Reflection;
> using System.Collections.Generic;
> using System.Text;
> using NUnit.Framework;
> using Seasar.Framework.Aop;
> using Seasar.Framework.Aop.Impl;
> using Seasar.Framework.Aop.Proxy;
> using Seasar.Framework.Aop.Interceptors;
>
> namespace Seasar.Tests.Framework.Aop.Interceptors
> {
> [TestFixture]
> public class InterceptorChainTest
> {
> private InterceptorChain target = null;
>
> public static object CreateProxy(IMethodInterceptor interceptor,
> Type proxyType) {
> IAspect aspect = new AspectImpl(interceptor, null);
> return new AopProxy(proxyType, new IAspect[] { aspect
> }).GetTransparentProxy();
> }
>
> [SetUp]
> public void SetUp() {
> target = new InterceptorChain();
> IMethodInterceptor interceptor1 = new TestInterceptor("_A");
> IMethodInterceptor interceptor2 = new TestInterceptor("_B");
> IMethodInterceptor interceptor3 = new
> MockInterceptor(TestMessage4InterceptorChain.ECHO);
> target.Add(interceptor1);
> target.Add(interceptor2);
> target.Add(interceptor3);
> }
>
> [Test]
> public void TestInvoke() {
> GoodMorning gm = CreateProxy(target, typeof(GoodMorning)) as
> GoodMorning;
> string result = gm.Greeting();
> Console.WriteLine(result);
> Assert.AreEqual(TestMessage4InterceptorChain.ECHO, result);
> }
> }
>
> public class TestMessage4InterceptorChain
> {
> public const string MSG = "hello";
> public const string ECHO = "echo";
> }
>
> public interface GoodMorning
> {
> string Greeting();
> }
>
> public class TestInterceptor : AbstractInterceptor
> {
> #region IMethodInterceptor クラス
>
> private readonly log4net.ILog _log =
> log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
> private string _id = "";
>
> public TestInterceptor(string id) {
> _id = id;
> }
>
> public override object Invoke(IMethodInvocation invocation) {
> Console.WriteLine(string.Format("{0} is called.",
> this.ToString() + _id));
> return invocation.Proceed();
> }
>
> #endregion
> }
> }
> ------------------------------------------------------------
>
> 以上です。
> よろしくお願い致します。
>
> ==========================================
> 小谷 圭
> kotani.k @ buildsystem.jp
> koya-tsuti2 @ u01.gate01.com
> ==========================================
--
Kazuya Sugimoto
http://d.hatena.ne.jp/sugimotokazuya/
seasar-dotnet メーリングリストの案内