PostSharp 1.0 Beta

The Creators of PostSharp – SharpCrafters なるものがリリースされたことを知りました.
こちらのエントリでも紹介されています → http://d.hatena.ne.jp/akiramei/20070307/p1


Aspect-Oriented Programming (AOP) については,http://www.postsharp.org/aop.net を参照してください.
Laos については,http://www.postsharp.org/about/components/laos を参照してください.
使用例の動画なんかもありますね → http://www.postsharp.org/documentation/simple-trace-aspect-tutorial/


http://doc.postsharp.org/ の Sample を眺めていたら興味が湧いてきたので,実験とかしてみたのですよ.


まずは,http://www.postsharp.org/documentation/simple-trace-aspect-tutorial/ を参考に,

namespace TestPostSharp
{
    [Serializable]
    class MyTraceAttribute : OnMethodBoundaryAspect
    {
        public override void OnEntry(MethodExecutionEventArgs eventArgs)
        {
            Console.WriteLine("入るよ> {0}", eventArgs.Method.Name);
        }

        public override void OnExit(MethodExecutionEventArgs eventArgs)
        {
            Console.WriteLine("出るよ> {0}", eventArgs.Method.Name);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Func("( ´Д`)つ [PostSharp]");
            Console.ReadKey();
        }

        [MyTrace]
        static void Func(string msg)
        {
            Console.WriteLine("なんか言ってみ> {0}", msg);
        }
    }
}

実行結果
Before

After


特定のメソッドだけに適用してみたり,

namespace TestPostSharp
{
    [Serializable]
    class MyTraceAttribute : OnMethodBoundaryAspect
    {
        public override void OnEntry(MethodExecutionEventArgs eventArgs)
        {
            Console.WriteLine("入るよ> {0}", eventArgs.Method.Name);
        }
        public override void OnExit(MethodExecutionEventArgs eventArgs)
        {
            Console.WriteLine("出るよ> {0}", eventArgs.Method.Name);
        }
    }

    [MyTrace(AttributeTargetMembers="Test*")]
    class Program
    {
        static void Main(string[] args)
        {
            TestAAA();
            BBB();
            TestCCC();
            Console.ReadKey();
        }
        
        static void TestAAA()
        {
            Console.WriteLine("TestAAAの中...");
        }
        
        static void BBB()
        {
            Console.WriteLine("BBBの中...");
        }

        static void TestCCC()
        {
            Console.WriteLine("TestCCCの中...");
        }
    }
}

実行結果


続いて,Sample から "Object Composition Sample" を試してみる.

namespace TestPostSharp
{
    [Serializable]
    public sealed class SimpleCompositionAttribute : CompositionAspect
    {
        string imTypeName;  // Implementation Type Name
        string ifTypeName;  // Interface Type Name

        public SimpleCompositionAttribute(Type interfaceType, Type implementationType)
        {
            if (implementationType != null)
            {
                this.imTypeName = implementationType.FullName;
            }
            if (interfaceType != null)
            {
                this.ifTypeName = interfaceType.FullName;
            }
        }

        public override object CreateImplementationObject(InstanceBoundLaosEventArgs eventArgs)
        {
            return Activator.CreateInstance(GenericArg.Map(Type.GetType(this.imTypeName)
                                                            , eventArgs.Instance.GetType().GetGenericArguments()
                                                            , null));
        }

        public override Type GetPublicInterface(Type containerType)
        {
            return GenericArg.Map(Type.GetType(this.ifTypeName), containerType.GetGenericArguments(), null);
        }
    }

    /// <summary>
    /// List&lt;T&gt;と合体して,IListを公開するクラス
    /// </summary>
    [SimpleComposition(typeof(IList<GenericTypeArg0>), typeof(List<GenericTypeArg0>))]
    class SimpleList<T>
    {
    }

    class Program
    {
        static void Main(string[] args)
        {
            SimpleList<string> sl = new SimpleList<string>();
            IList<string> il = (IList<string>)sl;

            il.Add("AAA");
            il.Add("BBB");
            il.Add("CCC");
            
            foreach (string s in il) Console.WriteLine(s);
            Console.ReadKey();
        }
    }
}

おお,合体した.


ちなみに,string から Type.GetTypeしているのは,

A minor issue appears: how to serialize both interface and implementation type names? We cannot simply serialize the Type instance, because it is not safely serializable. So we will store the type names in the class.

だそうな(そうだったんだ...).