3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

.NETCoreでのアスペクト指向メモ

Posted at

.NETCoreでのアスペクト指向メモ

この記事の前提

備忘録的に残すために記述したものです。

.NETCoreでのアスペクト指向

.NET CoreではRealProxyクラスがない。

代わりにDispatchProxyクラスを使う。

サンプルソース

AkProxy.cs

プロキシクラスです。

AkProxy.cs
using System;
using System.Diagnostics;
using System.Reflection;

namespace Ak.Sample.Core.Aspect
{
    public class AkProxy<T> : DispatchProxy
    {
        private T _instance;

        public static T Create(T instance)
        {
            object proxy = Create<T, AkProxy<T>>();
            ((AkProxy<T>)proxy).SetParameters(instance);

            return (T)proxy;
        }

        protected void SetParameters(T instance)
        {
            if (instance == null)
            {
                throw new ArgumentNullException(nameof(instance));
            }
            _instance = instance;
        }

        protected override object Invoke(MethodInfo targetMethod, object[] args)
        {
            Guid msgId = Guid.NewGuid();
            try
            {
                BeforeProcess(msgId, targetMethod, args);
                var result = targetMethod.Invoke(_instance, args);
                AfterProcess(msgId, targetMethod, args, result);

                return result;
            }
            catch (Exception ex) when (ex is TargetInvocationException)
            {
                ExceptionProcess(msgId, targetMethod, args, ex);
                throw ex.InnerException ?? ex;
            }
        }

        protected void BeforeProcess(Guid msgId, MethodInfo targetMethod, object[] args)
        {
            Console.WriteLine($"[{msgId.ToString()}][Method:{targetMethod.Name}] 処理を実行します。");
        }

        protected void AfterProcess(Guid msgId, MethodInfo targetMethod, object[] args, object result)
        {
            Console.WriteLine($"[{msgId.ToString()}][Method:{targetMethod.Name}] 処理が正常終了しました。");
        }

        protected void ExceptionProcess(Guid msgId, MethodInfo targetMethod, object[] args, Exception ex)
        {
            Console.WriteLine($"[{msgId.ToString()}][Method:{targetMethod.Name}] 例外が発生しました。");
            Console.WriteLine($"[{ex.ToString()}]");
        }
    }
}

MyClass.cs

ロジッククラスです。

MyClass.cs
using System;
using System.Collections.Generic;
using System.Text;

namespace Ak.Sample.Core.Aspect.Test.SampleClass
{
    public interface IMyClass
    {
        int Sum(int a, int b);
        int Quotient(int a, int b);
    }

    public class MyClass : IMyClass
    {
        public int Sum(int a ,int b)
        {
            return a + b;
        }

        public int Quotient(int a, int b)
        {
            return a / b;
        }
    }
}

UnitTest1.cs

ロジッククラスのメソッドの呼び出し処理です。(テストメソッド)

UnitTest1.cs
using Ak.Sample.Core.Aspect.Test.SampleClass;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.IO;
using System.Text;

namespace Ak.Sample.Core.Aspect.Test
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            IMyClass cls = AkProxy<IMyClass>.Create(new MyClass());
            Console.WriteLine(cls.Sum(1,2));
        }

        [TestMethod]
        public void TestMethod2()
        {
            try
            {
                IMyClass cls = AkProxy<IMyClass>.Create(new MyClass());
                Console.WriteLine(cls.Quotient(2, 0));
                Assert.Fail();
            }
            catch (Exception)
            {
            }
        }
    }
}

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?