[seasar-dotnet:356] S2Container.NET上でのInterceptorChainについて
kk
koya-tsuti2 @ u01.gate01.com
2006年 10月 1日 (日) 13:16:19 JST
初めまして。
小谷と申します。
いつもお世話になっております。
表題の件について要望があります。
現在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
==========================================
seasar-dotnet メーリングリストの案内