Atilla Tanrikulu

I am an experienced software engineer and architect living in Germany. I’m passionate about distributed scalable enterprise web-based microservices/applications and delivering great user experiences. I have created some amazing enterprise-level applications that many people have used and hopefully enjoyed.

Articles

Java Quick Reference Apache Kafka Tutorial Guvenli Kod Gelistirme Making an Enterprise Scale Angular Project Step by Step Nightly SQL Server Database Backup with command line batch file and windows scheduler AOP Framework without proxy pattern IdentityServer Nedir Middleware Pattern With Csharp And Javascript Docker most used commands Online Proje Dokumantasyonu, Docker, Nginx, mdwiki How to use Github Pages for static websites Inheritance with JavaScript, EC6 (ECMAScript 6, ECMAScript 2015) Object oriented javascript and Inheritance Singleton Pattern with Javascript Factory Pattern with Javascript Open terminal here mac os x service IdentityServer4-Angular-6-integration JMater notlari, kurulum ve kullanim Learn Jekyll in 12 Steps Make Mac Application with Automater from sh script Make spotlight index markdown or code files OAuth 2.0 Nedir (RFC6749) Using Custom CSS and Custom JavaScript to an Angular Project Cross Platform Desktop Application With .Net Core 2x and Angular 6x front-end projects with nodejs gulp bower yeoman and angularjs Host Asp.Net Core on Linux with Apache Redis kurulumu ve ayarlari Useful Mac OS Apps Choosing internet connection on multiple interface windows Name Server Kurulumu How to define domain name for your dynamic IP SQL table data compare, and prepare insert satements Useful Git Commands TFS ile Otomatik deployment yapmak Spring Boot Tutorial Sql server icin maliyetli sorgularin tespit edilmesi Arama Motoru Optimizasyonu (SEO) My installed mac apps

AOP Framework without proxy pattern

AOP addresses the problem of cross-cutting concerns, which would be any kind of code that is repeated in different methods. separating of concerns prevents code repetitions.

People generally use proxy pattern (Dynamic Proxy generators) for Applying AOP in C#, This example don’t use dynamic proxy generators, it is simple because it uses only function definition.

example code

robo-aspect-framework

Attributes for AOP

public class PersonService : BaseService, IPersonService
{
    [Cache]
    [Log]
    public virtual string Method1(int x)
    {
        return $"input is {x}";
    }
}

Invoking Methods:


PersonService personService = new PersonService();

var result = personService.Invoke<string>(() => personService.Method1(3));

Invoker:


public static class Invoker
{
    public static object Invoke(InvokeContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        Expression<Func<object>> _function = context.Request.Function;
        object _instance = context.Request.Instance;

        var timer = Stopwatch.StartNew();
        if (_instance == null) throw new Exception("Service is null!");
        var fbody = _function.Body as MethodCallExpression;
        if (fbody == null || fbody.Method == null) throw new Exception("Expression must be a method call.");
        string methodName = fbody.Method.Name;
        dynamic result = null;

        List<object> args = new List<object>();

        foreach (var argument in fbody.Arguments)
        {
            var constant = argument as ConstantExpression;
            if (constant != null)
            {
                args.Add(constant.Value);
            }
        }

        IEnumerable<Attribute> aspects = _instance.GetType().GetMethod(methodName).GetCustomAttributes(true);

        RunBeforeAspects(context, aspects);

        //if cache aspect or other aspects, returns response.
        if (context?.Result?.Value != null)
        {
            return context.Result.Value;
        }

        try
        {
            result = fbody.Method.Invoke(_instance, args.ToArray<object>());
            Type t = context.Result.ResultType;
            context.Result.Value = result;
        }
        catch (Exception e)
        {
            throw e;
        }
        finally
        {
            timer.Stop();
            Console.WriteLine($"{methodName}() method invoked in :{Convert.ToDouble(timer.ElapsedMilliseconds)}ms ");
        }

        RunAfterAspects(context, aspects);

        return result;
    }

    private static void RunBeforeAspects(InvokeContext context, IEnumerable<Attribute> aspects)
    {
        foreach (var aspect in aspects)
        {
            if (aspect.GetType().GetTypeInfo().BaseType == typeof(AspectBase))
            {
                ((IAspect)aspect).OnBefore(context);
            }
        }
    }

    private static void RunAfterAspects(InvokeContext context, IEnumerable<Attribute> aspects)
    {
        foreach (var aspect in aspects)
        {
            if (aspect.GetType().GetTypeInfo().BaseType == typeof(AspectBase))
            {
                ((IAspect)aspect).OnAfter(context);
            }
        }
    }
}
Date: 2017-11-23 10:20:00 +0000