{"id":443,"date":"2015-09-13T02:19:45","date_gmt":"2015-09-12T23:19:45","guid":{"rendered":"https:\/\/gokhan-gokalp.com\/?p=443"},"modified":"2015-09-13T02:22:34","modified_gmt":"2015-09-12T23:22:34","slug":"aspect-oriented-programming-aop-giris-ve-ornek-bir-proje","status":"publish","type":"post","link":"https:\/\/gokhan-gokalp.com\/tr\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\/","title":{"rendered":"Aspect Oriented Programming (AOP) &#8211; Giri\u015f ve \u00d6rnek Bir Proje"},"content":{"rendered":"<p>Merhaba arkada\u015flar, bu\u00a0makalemde <strong>Aspect Oriented Programming (AOP) <\/strong>nedir\u00a0ve birbirleri ile kesi\u015fen ilgiler\u00a0<strong>(Cross-Cutting)<\/strong>\u00a0nelerdir gibi kavramlar\u0131 a\u00e7\u0131klayarak <strong>AOP<\/strong> serisine bir giri\u015f yapmak istiyorum.<\/p>\n<p>Uzun zamand\u0131r giri\u015f yapmay\u0131 d\u00fc\u015f\u00fcnd\u00fc\u011f\u00fcm bir konuydu asl\u0131nda AOP fakat\u00a0f\u0131rsat bulup bir t\u00fcrl\u00fc ba\u015flayamam\u0131\u015ft\u0131m. Umar\u0131m keyifli bir makale serisi \u00e7\u0131kar. :)<\/p>\n<p><a href=\"\/wp-content\/uploads\/2015\/09\/aop.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-454 lazyload\" data-src=\"\/wp-content\/uploads\/2015\/09\/aop.jpg\" alt=\"aop\" width=\"571\" height=\"405\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2015\/09\/aop.jpg 571w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2015\/09\/aop-300x213.jpg 300w\" data-sizes=\"(max-width: 571px) 100vw, 571px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 571px; --smush-placeholder-aspect-ratio: 571\/405;\" \/><\/a><\/p>\n<h3>AOP Nedir ve Neden \u0130htiya\u00e7 Duyar\u0131z?<\/h3>\n<p>Aspect Oriented Programming yakla\u015f\u0131m\u0131, temelinde birbirleri ile kesi\u015fen ilgilerin <strong>(Cross-Cutting Concerns)<\/strong> ayr\u0131lmas\u0131 \u00fczerinedir. Peki nedir bu birbirleri ile kesi\u015fen ilgiler diyecek olursak:<\/p>\n<p>Geli\u015ftirdi\u011fimiz mod\u00fcllere bakt\u0131\u011f\u0131m\u0131zda asl\u0131nda her business i\u015fleminde ortak olarak ger\u00e7ekle\u015ftirdi\u011fimiz baz\u0131 i\u015flemler vard\u0131r. \u00d6rne\u011fin kullan\u0131c\u0131n\u0131n yetkisi var m\u0131?, Gelen iste\u011fi logla, Exception Handling i\u015flemini yap gibi ve sonras\u0131nda ilgili mod\u00fcl\u00fcn business k\u0131sm\u0131n\u0131 ger\u00e7ekle\u015ftirmekteyiz. \u0130\u015fte bu i\u015flemler bizim birbirleri ile kesi\u015fen ilgilerimiz (Cross-Cutting-Concerns) oluyor.<\/p>\n<p>Bu mod\u00fcle birde kodsal a\u00e7\u0131dan \u00f6rnek vermek gerekirse:<\/p>\n<pre class=\"lang:c# decode:true\">        public Product GetProduct(int productId)\r\n        {\r\n            try\r\n            {\r\n                \/\/ Kullan\u0131c\u0131 yetkilerini kontrol et.\r\n                \/\/ Yap\u0131lan i\u015flemi logla.\r\n\r\n                var product = new Product();\r\n                \/\/ Product'\u0131 cache'e ilgili productId ile ekle.\r\n\r\n                return product;\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                \/\/ Exception handling i\u015flemleri.\r\n                throw;\r\n            }\r\n        }<\/pre>\n<p>\u00d6rnek metot \u00fczerinde de g\u00f6rd\u00fc\u011f\u00fcm\u00fcz \u00fczere genelde business i\u015flemi s\u0131ras\u0131nda yapt\u0131\u011f\u0131m\u0131z temel kontrol ve i\u015flemler. AOP ise bize birbirleri ile kesi\u015fen bu ilgilerin birbirlerinden farkl\u0131 olsada\u00a0ayr\u0131lmalar\u0131 gerekti\u011fini s\u00f6ylemektedir.<\/p>\n<p>Aspect Oriented Programming&#8217;in\u00a0odak noktas\u0131 ise<strong> konular\u0131n ayr\u0131m\u0131d\u0131r<\/strong> <strong>(Separation of Concerns)<\/strong>. Object Oriented Programming&#8217;de de oldu\u011fu \u00fczere\u00a0olu\u015fturmu\u015f oldu\u011fumuz s\u0131n\u0131flar\u0131, her s\u0131n\u0131f\u0131n kendi sorumlulu\u011funu yerine getirmesi <strong>(Single Responsibility)\u00a0<\/strong>gibi prensiplere uyarak geli\u015ftirdi\u011fimizde olu\u015fan kodun okunabilirli\u011fini <strong>(Readability)<\/strong>, tekrar kullanabilirli\u011fini<strong> (Reusability)<\/strong> ve geni\u015fletilebilirli\u011fini <strong>(Extensibility)<\/strong> sa\u011flamaktay\u0131z. AOP ise bize bu anlamda kodun okunabilirli\u011fini ve tekrar kullan\u0131labilirli\u011fini en \u00fcst seviyede sa\u011flamay\u0131 ama\u00e7lamaktad\u0131r konular\u0131n ayr\u0131m\u0131 (Separation of Concerns)\u00a0alt\u0131nda.<\/p>\n<p>Object Oriented Programming&#8217;de soyutlamaya\u00a0(Abstraction) giderekte kodun tekrar kullan\u0131labilirli\u011fini, okunabilirli\u011fini ve geni\u015fletilebilirli\u011fini ve s\u0131n\u0131flar\u0131n birbirine s\u0131k\u0131 s\u0131k\u0131ya ba\u011fl\u0131 <strong>(Tightly Coupled)<\/strong> olmamas\u0131n\u0131 sa\u011flayabiliriz ama bir noktaya\u00a0kadar. O nokta geldi\u011finde ise AOP kesi\u015fen ilgilerimizi\u00a0ele alarak onlar\u0131 tamamen ba\u011f\u0131ms\u0131z <strong>(Independent)\u00a0<\/strong>hale getirmektedir. Bu sayede her bir kesi\u015fen ilgimiz, kendi i\u00e7erisinde ba\u011f\u0131ms\u0131z olarak geli\u015ftirilebilir ve tekrar kullan\u0131labilir hale gelmektedir.<\/p>\n<p>Yukar\u0131daki \u00f6rnek \u00fczerine AOP uygulayarak yeni bir \u00f6rnek vermek gerekirse:<\/p>\n<pre class=\"lang:c# decode:true \">        [ExceptionHandling]\r\n        [CheckUserAuthorization]\r\n        [LogProcess]\r\n        [Cache(TimeOut = 10000)]\r\n        public Product GetProduct(int productId)\r\n        {\r\n            var product = new Product();\r\n            return product;\r\n        }<\/pre>\n<p>Kesi\u015fen ilgilerimizi\u00a0(Cross-Cutting-Concerns)\u00a0AOP ile ay\u0131rd\u0131ktan sonraki hali ger\u00e7ekten \u015faka gibi de\u011fil mi? :) Okunabilirlik ve tekrar kullan\u0131labilirli\u011fi nas\u0131lda de\u011fi\u015fti\u011fini net\u00e7e g\u00f6rebiliyoruz. A\u00e7\u0131k\u00e7as\u0131 bu \u015fekilde yap\u0131lar geli\u015ftirmek, insana kod yazarken de ayr\u0131 bir zevk veriyor do\u011frusu.<\/p>\n<p>Evet, i\u015fin terminoloji k\u0131s\u0131mlar\u0131nda her \u015fey g\u00fczel. Fakat biz bu kesi\u015fen ilgilerimizi nas\u0131l ay\u0131raca\u011f\u0131z sorununa gelirsek, bu konuda yard\u0131m\u0131m\u0131za <strong>Interceptor<\/strong> yap\u0131lar\u0131 \u00e7\u0131kmakta. Interceptor&#8217;ler bize metot \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda,\u00a0\u00f6ncesinde ve sonras\u0131nda araya girerek belirli i\u015flemleri yapabilmemizi sa\u011flayan yap\u0131lard\u0131r.<\/p>\n<p>Interceptor yap\u0131lar\u0131n\u0131 olu\u015fturabilmek i\u00e7in <strong>Reflection <\/strong>s\u0131n\u0131f\u0131ndan bolca yararlanaca\u011f\u0131z. :) \u0130\u015fin asl\u0131, bu yap\u0131lar\u0131 kolayl\u0131kla kullanabilmek i\u00e7in bir \u00e7ok 3rd party uygulama bulunmakta. \u00d6rne\u011fin:\u00a0Castle Windsor, Enterprise Library gibi k\u00fct\u00fcphaneler. Ben en az\u0131ndan giri\u015f makalemde i\u015fin mutfa\u011f\u0131nda neler olup bitiyoru sizlere g\u00f6stermeden haz\u0131r k\u00fct\u00fcphaneler arac\u0131l\u0131\u011f\u0131 ile bu yap\u0131lar\u0131 kullanmak istemiyorum. Bu y\u00fczden i\u015fin e\u011flenceli k\u0131sm\u0131 olan kendi interceptor&#8217;\u00fcm\u00fcz\u00fc olu\u015fturaca\u011f\u0131z. Bu mutfa\u011f\u0131n bir kokusunu alal\u0131m ve neler olup bitiyor bir bilelim en az\u0131ndan. :)<\/p>\n<p>\u015eimdi i\u015fin en e\u011flenceli k\u0131sm\u0131na ge\u00e7me vakti. \u00d6rne\u011fimizde bizim kesi\u015fen ilgilerimiz a\u015fa\u011f\u0131daki mod\u00fcller olsun:<\/p>\n<ul>\n<li>Caching<\/li>\n<li>Loging<\/li>\n<\/ul>\n<p>Bu mod\u00fcllerimiz&#8217;i birbirlerinden ba\u011f\u0131ms\u0131z concern&#8217;lara ay\u0131rarak aspect&#8217;ler arac\u0131l\u0131\u011f\u0131 ile metotlar\u0131n \u00e7a\u011f\u0131r\u0131m\u0131nda, nas\u0131l araya girerek i\u015flemlerimizi ger\u00e7ekle\u015ftirebilece\u011fimizi g\u00f6relim.<\/p>\n<p><strong>AOPGiris<\/strong> isimli bir konsol uygulamas\u0131 olu\u015fturuyorum. Konsol uygulamas\u0131n\u0131n i\u00e7erisine\u00a0<strong>Aspect<\/strong> isimli bir klas\u00f6r olu\u015fturuyorum ve\u00a0Aspect&#8217;lerimizi burada geli\u015ftirece\u011fiz.\u00a0<strong>IAspect<\/strong> isimli bir interface ekliyorum ve bu interface&#8217;i implemente ederek aspect modlar\u0131m\u0131z\u0131 olu\u015fturaca\u011f\u0131z.<\/p>\n<pre class=\"lang:c# decode:true \">namespace AOPGiris.Aspect\r\n{\r\n    public interface IAspect\r\n    {\r\n    }\r\n}<\/pre>\n<p>\u015eimdi ise IAspect interface&#8217;ini implemente ederek, aspect modlar\u0131m\u0131z\u0131 olu\u015fturaca\u011f\u0131z. Bu modlar ise bize metot \u00e7a\u011fr\u0131m\u0131nda\u00a0\u00f6ncesinde veya sonras\u0131nda araya girebilmemizi sa\u011flayacaklar.<\/p>\n<pre class=\"lang:c# decode:true \">namespace AOPGiris.Aspect\r\n{\r\n    public interface IAfterAspect : IAspect\r\n    {\r\n        object OnAfter(object value);\r\n    }\r\n}<\/pre>\n<p><strong>IAfterAspect<\/strong>\u00a0metot i\u015flendikten sonra \u00e7al\u0131\u015facak olan aspect modudur\u00a0ve geriye herhangi bir i\u015flem de\u011feri d\u00f6nmektedir.<\/p>\n<pre class=\"lang:c# decode:true \">namespace AOPGiris.Aspect\r\n{\r\n    public interface IAfterVoidAspect : IAspect\r\n    {\r\n        void OnAfter(object value);\r\n    }\r\n}<\/pre>\n<p><strong>IAfterVoidAspect<\/strong> ise imzas\u0131ndan da anla\u015f\u0131laca\u011f\u0131 \u00fczere metot i\u015flendikten sonra \u00e7al\u0131\u015f\u0131p geriye de\u011fer d\u00f6nmemektedir.<\/p>\n<pre class=\"lang:c# decode:true\">namespace AOPGiris.Aspect\r\n{\r\n    interface IBeforeAspect : IAspect\r\n    {\r\n        object OnBefore();\r\n    }\r\n}<\/pre>\n<p><strong>IBeforeAspect<\/strong> ise metot i\u015flenmeden \u00f6nce \u00e7al\u0131\u015facak olan aspect modumuzdur.<\/p>\n<pre class=\"lang:c# decode:true\">namespace AOPGiris.Aspect\r\n{\r\n    public interface IBeforeVoidAspect : IAspect\r\n    {\r\n        void OnBefore();\r\n    }\r\n}<\/pre>\n<p><strong>IBeforeVoidAspect<\/strong> ise metot i\u015flenmeden \u00f6nce \u00e7al\u0131\u015f\u0131p geriye de\u011fer d\u00f6nmeyecek olan aspect modumuzdur.\u00a0\u015eimdi s\u0131ra geldi kesi\u015fen ilgilerimizin aspectlerini olu\u015fturmak i\u00e7in t\u00fcrece\u011fimiz abstract s\u0131n\u0131f\u0131m\u0131z\u0131 olu\u015fturmaya.<\/p>\n<pre class=\"lang:c# decode:true\">using System;\r\n\r\nnamespace AOPGiris.Aspect\r\n{\r\n    public abstract class AspectBase : Attribute, IAspect\r\n    {\r\n\r\n    }\r\n}<\/pre>\n<p><strong>AspectBase<\/strong> s\u0131n\u0131f\u0131n\u0131,\u00a0Attribute soyut s\u0131n\u0131f\u0131ndan t\u00fcretiyoruz ve olu\u015fturmu\u015f oldu\u011fumuz <strong>IAspect<\/strong> aray\u00fcz\u00fcn\u00fcde implemente ediyoruz. Alt yap\u0131m\u0131z haz\u0131r oldu\u011funa g\u00f6re \u015fimdi mod\u00fcllerimiz&#8217;i olu\u015fturmaya ba\u015flayabiliriz.<\/p>\n<p>\u0130lgili aspect&#8217;leri\u00a0olu\u015fturmadan \u00f6nce mod\u00fcl i\u015flemleri s\u0131ras\u0131nda bize unique\u00a0key&#8217;ler olu\u015fturabilme gibi i\u015flemler i\u00e7in\u00a0ilgili metot&#8217;un ismini, \u00e7a\u011f\u0131r\u0131m s\u0131ras\u0131nda g\u00f6nderilen parametreleri verecek olan yard\u0131mc\u0131 s\u0131n\u0131f amac\u0131 ile\u00a0<strong>AspectContext<\/strong> isimli bir s\u0131n\u0131f olu\u015fturuyorum.<\/p>\n<pre class=\"lang:c# decode:true \">using System;\r\n\r\nnamespace AOPGiris.Aspect\r\n{\r\n    public class AspectContext\r\n    {\r\n        private readonly static Lazy&lt;AspectContext&gt; _Instance = new Lazy&lt;AspectContext&gt;(() =&gt; new AspectContext());\r\n\r\n        private AspectContext()\r\n        {\r\n        }\r\n\r\n        public static AspectContext Instance\r\n        {\r\n            get\r\n            {\r\n                return _Instance.Value;\r\n            }\r\n        }\r\n\r\n        public string MethodName { get; set; }\r\n        public object[] Arguments { get; set; }\r\n    }\r\n}<\/pre>\n<p><strong>Lazy<\/strong> s\u0131n\u0131f\u0131 arac\u0131l\u0131\u011f\u0131 ile pratik olarak\u00a0<strong>Singleton<\/strong> desenini uyguluyorum ve bize mod\u00fcl i\u015flemleri s\u0131ras\u0131nda gerekli olacak\u00a0property&#8217;leri tan\u0131ml\u0131yorum.\u00a0Aspect klas\u00f6r\u00fcn\u00fcn i\u00e7erisine\u00a0<strong>Attributes<\/strong> isimli yeni bir klas\u00f6r\u00a0olu\u015fturuyorum ve ilk mod\u00fcl\u00fcm\u00fcz olan caching i\u015flemleri i\u00e7in kullanacak oldu\u011fumuz <strong>CacheAttribute<\/strong> s\u0131n\u0131f\u0131n\u0131 kodlamaya ba\u015fl\u0131yorum.<\/p>\n<pre class=\"lang:c# decode:true\">using System;\r\n\r\nnamespace AOPGiris.Aspect.Attributes\r\n{\r\n    public class CacheAttribute : AspectBase, IBeforeAspect, IAfterVoidAspect\r\n    {\r\n        public int DurationInMinute { get; set; }\r\n\r\n        public object OnBefore()\r\n        {\r\n            string cacheKey = string.Format(\"{0}_{1}\", AspectContext.Instance.MethodName, string.Join(\"_\", AspectContext.Instance.Arguments));\r\n\r\n            if(true)\r\n            {\r\n                \/\/ gerekli cache key ile kontrol ederek varsa cache'de \u00e7a\u011f\u0131r\u0131m \u00f6ncesi metot'u execute\r\n                \/\/ etmeden cache \u00fczerinden ilgili veriyi geri d\u00f6n.\r\n\r\n                Console.WriteLine(\"{0} isimli cache key ile cache \u00fczerinden geliyorum!\", cacheKey);\r\n                return true;\r\n            }\r\n        }\r\n\r\n        public void OnAfter(object value)\r\n        {\r\n            string cacheKey = string.Format(\"{0}_{1}\", AspectContext.Instance.MethodName, string.Join(\"_\", AspectContext.Instance.Arguments));\r\n\r\n            \/\/ cache key ile ilgili veriyi DurationInMinute kullanarak Cache'e ekle veya g\u00fcncelle.\r\n        }\r\n    }\r\n}<\/pre>\n<p><strong>IBeforeAspect<\/strong> ve <strong>IAfterVoidAspect<\/strong> kullanarak olu\u015fturmu\u015f oldu\u011fum CacheAttribute&#8217;\u00fc \u00e7a\u011f\u0131r\u0131m \u00f6ncesi metot execute edilmeden araya girerek cache kontrol\u00fc yapar ve varsa cache \u00fczerinden getirerek geriye de\u011feri d\u00f6ner. OnAfter&#8217;da ise ilgili i\u015flem execute edildikten sonra veri cache&#8217;e eklenir veya g\u00fcncellenir. Cache i\u015flemimiz bu kadar :) \u015eimdi s\u0131ra Loging i\u015flemine. Attributes klas\u00f6r\u00fc i\u00e7erisinde \u015fimdide <strong>LogAttribute<\/strong> s\u0131n\u0131f\u0131 olu\u015fturuyorum ve kodlamaya devam ediyoruz.<\/p>\n<pre class=\"lang:c# decode:true\">using System;\r\nusing System.Text;\r\n\r\nnamespace AOPGiris.Aspect.Attributes\r\n{\r\n    public class LogAttribute : AspectBase, IBeforeVoidAspect, IAfterVoidAspect\r\n    {\r\n        public void OnBefore()\r\n        {\r\n            StringBuilder sbLogMessage = new StringBuilder();\r\n\r\n            sbLogMessage.AppendLine(string.Format(\"Method Name: {0}\", AspectContext.Instance.MethodName));\r\n            sbLogMessage.AppendLine(string.Format(\"Arguments: {0}\", string.Join(\",\", AspectContext.Instance.Arguments)));\r\n\r\n            \/\/ log i\u015flemini ger\u00e7ekle\u015ftir.\r\n            Console.WriteLine(\"Loging: {0}\", sbLogMessage.ToString());\r\n        }\r\n\r\n        public void OnAfter(object value)\r\n        {\r\n            \/\/ sonras\u0131nda log tutmak istenirse.\r\n        }\r\n    }\r\n}<\/pre>\n<p><strong>IBeforeVoidAspect<\/strong> ve <strong>IAfterVoidAspect<\/strong> kullanarak olu\u015fturmu\u015f oldu\u011fum LogAttribute s\u0131n\u0131f\u0131da \u00f6ncesinde loglama i\u015flemini ger\u00e7ekle\u015ftiriyoruz ve geriye herhangi bir de\u011fer d\u00f6nmemize gerek olmad\u0131\u011f\u0131 i\u00e7in <strong>IBeforeVoidAspect<\/strong> t\u00fcr\u00fcn\u00fc implemente ettik. OnAfter&#8217;da ise ilgili veriyi i\u015flem sonras\u0131 loglama yapabiliriz.<\/p>\n<p>Aspectler bu kadar. \u015eimdi s\u0131ra geldi as\u0131l s\u0131k\u0131nt\u0131l\u0131 k\u0131s\u0131ma :) Araya girmemizi sa\u011flayacak olan proxy s\u0131n\u0131f\u0131n\u0131 tasarlayaca\u011f\u0131z. <strong>Transparent Proxy<\/strong> s\u0131n\u0131f\u0131 bizim ger\u00e7ek s\u0131n\u0131f\u0131m\u0131z\u0131 temsil ediyor olacak ve ilgili metot&#8217;u invoke etmeden \u00f6nce veya sonras\u0131nda istedi\u011fimiz i\u015flemleri yapabiliyor olaca\u011f\u0131z. Bu i\u015flemi yapan haz\u0131r k\u00fct\u00fcphaneler oldu\u011fundan bahsetmi\u015ftik, EL i\u00e7indeki Unity veya Castle Windsor gibi.<\/p>\n<p>Bu k\u00fct\u00fcphanelerde ger\u00e7ek nesnelerimizin \u00e7al\u0131\u015fma zaman\u0131nda birer Transparent Proxy&#8217;lerini olu\u015fturarak araya girme i\u015flemlerini ger\u00e7ekle\u015ftirmektedirler. Bu i\u015flemide kendimiz handle edece\u011fimiz i\u00e7in ba\u015flayal\u0131m generic bir\u00a0<strong>TransparentProxy<\/strong> s\u0131n\u0131f\u0131n\u0131 kodlamaya.<\/p>\n<pre class=\"lang:c# decode:true\">using AOPGiris.Aspect;\r\nusing System;\r\nusing System.Runtime.Remoting.Messaging;\r\nusing System.Runtime.Remoting.Proxies;\r\n\r\nnamespace AOPGiris\r\n{\r\n    public class TransparentProxy&lt;T, TI&gt; : RealProxy where T : TI, new() \/\/ \u0130lgili tipin \u00f6rne\u011fini alabilmek i\u00e7in new() constraint'ini ekliyoruz.\r\n    {\r\n        private TransparentProxy()\r\n            : base(typeof(TI)) \/\/ RealProxy s\u0131n\u0131f\u0131na, ger\u00e7ek nesnemizi temsil edecek olan tipi veriyoruz, ilgili interface'imiz.\r\n        {\r\n\r\n        }\r\n\r\n        \/\/ \u0130lgili tipte RealProxy arac\u0131l\u0131\u011f\u0131 ile proxy'mizi olu\u015fturuyoruz.\r\n        public static TI GenerateProxy()\r\n        {\r\n            var instance = new TransparentProxy&lt;T,TI&gt;();\r\n            return (TI)instance.GetTransparentProxy();\r\n        }\r\n\r\n        \/\/ \u0130lgili metot \u00e7a\u011f\u0131r\u0131ld\u0131\u011f\u0131nda \u00e7al\u0131\u015facak olan metotdur.\r\n        public override IMessage Invoke(IMessage msg)\r\n        {\r\n            var methodCallMessage = msg as IMethodCallMessage;\r\n            ReturnMessage returnMessage = null;\r\n\r\n            try\r\n            {\r\n                \/\/ tipimiz \u00fczerinden metot infoya eri\u015ferek ilgili attribute olarak eklenmi\u015f\r\n                \/\/ aspect'lerimizi buluyoruz.\r\n                var realType = typeof(T);\r\n                var mInfo = realType.GetMethod(methodCallMessage.MethodName);\r\n                var aspects = mInfo.GetCustomAttributes(typeof(IAspect), true);\r\n\r\n                \/\/ Hat\u0131rlarsan\u0131z aspect'lerimiz i\u00e7erisinde kullanm\u0131\u015ft\u0131k. Gelen parametreleri dolduruyoruz context'e.\r\n                FillAspectContext(methodCallMessage);\r\n\r\n                object response = null;\r\n\r\n                \/\/ Before aspectlerimizi \u00e7al\u0131\u015ft\u0131r\u0131yoruz \u00f6nce ve geriye de\u011fer d\u00f6nen varsa respons'a e\u015fitliyoruz.\r\n                CheckBeforeAspect(response, aspects);\r\n\r\n                object result = null;\r\n\r\n                \/\/ Response bo\u015f de\u011filse, buradaki veri cache \u00fczerinden de geliyor olabilir ve tekrardan invoke etmeye\r\n                \/\/ gerek yok, direkt olarak geriye response d\u00f6nebiliriz bu durumda.\r\n                if (response != null)\r\n                {\r\n                    returnMessage = new ReturnMessage(response, null, 0, methodCallMessage.LogicalCallContext, methodCallMessage);\r\n                }\r\n                else\r\n                {\r\n                    \/\/ Response bo\u015f ise ilgili metot'u art\u0131k invoke ederek \u00e7al\u0131\u015ft\u0131r\u0131yor ve sonucunu al\u0131yoruz.\r\n                    result = methodCallMessage.MethodBase.Invoke(new T(), methodCallMessage.InArgs);\r\n                    returnMessage = new ReturnMessage(result, null, 0, methodCallMessage.LogicalCallContext, methodCallMessage);\r\n                }\r\n\r\n                CheckAfterAspect(result, aspects);\r\n\r\n                \/\/ After aspectlerimizi'de \u00e7al\u0131\u015ft\u0131rd\u0131ktan sonra art\u0131k geriye \u00e7\u0131kt\u0131y\u0131 d\u00f6nebiliriz.\r\n                return returnMessage;\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                return new ReturnMessage(ex, methodCallMessage);\r\n            }\r\n        }\r\n\r\n        private void FillAspectContext(IMethodCallMessage methodCallMessage)\r\n        {\r\n            AspectContext.Instance.MethodName = methodCallMessage.MethodName;\r\n            AspectContext.Instance.Arguments = methodCallMessage.InArgs;\r\n        }\r\n\r\n        private void CheckBeforeAspect(object response, object[] aspects)\r\n        {\r\n            foreach (IAspect loopAttribute in aspects)\r\n            {\r\n                if (loopAttribute is IBeforeVoidAspect)\r\n                {\r\n                    ((IBeforeVoidAspect)loopAttribute).OnBefore();\r\n                }\r\n                else if (loopAttribute is IBeforeAspect)\r\n                {\r\n                    response = ((IBeforeAspect)loopAttribute).OnBefore();\r\n\r\n                }\r\n            }\r\n        }\r\n\r\n        private void CheckAfterAspect(object result, object[] aspects)\r\n        {\r\n            foreach (IAspect loopAttribute in aspects)\r\n            {\r\n                if (loopAttribute is IAfterVoidAspect)\r\n                {\r\n                    ((IAfterVoidAspect)loopAttribute).OnAfter(result);\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>TransparentProxy s\u0131n\u0131f\u0131m\u0131z&#8217;da haz\u0131r durumda. \u0130lgili bilgileri metot yorum sat\u0131rlar\u0131nda bulabilirsiniz. Art\u0131k ilgili s\u0131n\u0131flar\u0131m\u0131z i\u00e7in RealProxy arac\u0131l\u0131\u011f\u0131 ile temsilcilik yapacak olan Generic Transparent Proxy s\u0131n\u0131f\u0131m\u0131z haz\u0131r ve kod i\u00e7erisinde de g\u00f6rebilece\u011finiz gibi aspect&#8217;lerimizide implemente etmi\u015f durumday\u0131z.<\/p>\n<p>\u015eimdi kodlam\u0131\u015f oldu\u011fumuz aspect&#8217;leri test edebilmemiz i\u00e7in bir <strong>ProductService <\/strong>isminde\u00a0s\u0131n\u0131f olu\u015fturuyorum ve i\u00e7erisine <strong>GetProduct<\/strong> metodunu olu\u015fturarak aspect&#8217;lerimizi i\u015faretliyorum.<\/p>\n<pre class=\"lang:c# decode:true \">using System.Collections.Generic;\r\nusing AOPGiris.Aspect.Attributes;\r\n\r\nnamespace AOPGiris\r\n{\r\n    public class Product\r\n    {\r\n        public int Id { get; set; }\r\n        public string Name { get; set; }\r\n        public double Price { get; set; }\r\n    }\r\n    public class ProductService\r\n    {\r\n        \/\/ In memory olarak bir ka\u00e7 product ekliyorum.\r\n        private static Dictionary&lt;int, Product&gt; _InMemDb = new Dictionary&lt;int, Product&gt;();\r\n\r\n        public ProductService()\r\n        {\r\n            _InMemDb.Add(1, new Product() { Id = 1, Name = \"MacBook Air\", Price = 3000 });\r\n            _InMemDb.Add(2, new Product() { Id = 2, Name = \"Sony Xperia Z Ultra\", Price = 1400 });\r\n        }\r\n\r\n        [Cache(DurationInMinute = 10)]\r\n        [Log]\r\n        public Product GetProduct(int productId)\r\n        {\r\n            return _InMemDb[productId];\r\n        }\r\n    }\r\n}<\/pre>\n<p><strong>ProductService<\/strong> s\u0131n\u0131f\u0131 i\u00e7in yeni bir \u00f6rne\u011fi al\u0131nd\u0131\u011f\u0131nda in memory olarak bir dictionary \u00fczerinde <strong>Product<\/strong> nesnelerini tutuyorum. <strong>GetProduct<\/strong> metodunda ise g\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi sadece dictionary \u00fczerinden nesneyi geri return ediyorum. Caching ve Loging i\u015flemlerini bizim i\u00e7in aspect&#8217;lerimiz halledecek. Ne kadarda ho\u015f duruyor de\u011fil mi? :)<\/p>\n<p>\u015eimdi konsol uygulamam\u0131z \u00fczerinde <strong>TransparentProxy\u00a0<\/strong>s\u0131n\u0131f\u0131m\u0131z arac\u0131l\u0131\u011f\u0131 ile \u00e7a\u011f\u0131rarak bir bakal\u0131m aspect&#8217;lerimiz nas\u0131l \u00e7al\u0131\u015facaklar?<\/p>\n<pre class=\"lang:c# decode:true \">using System;\r\n\r\nnamespace AOPGiris\r\n{\r\n    class Program\r\n    {\r\n        static void Main(string[] args)\r\n        {\r\n            \/\/ Servis \u00f6rne\u011fini olu\u015fturuyoruz.\r\n            var productService = TransparentProxy&lt;ProductService, IProductService&gt;.GenerateProxy();\r\n\r\n            \/\/ Servis \u00fczerinden GetProduct metotunu \u00e7a\u011f\u0131r\u0131yoruz.\r\n            var product = productService.GetProduct(1);\r\n\r\n            Console.WriteLine(\"Id: {0}, Name: {1}, Price: {2}\", product.Id, product.Name, product.Price);\r\n            Console.ReadLine();\r\n        }\r\n    }\r\n}<\/pre>\n<p>ve sonu\u00e7&#8230;<\/p>\n<p><a href=\"\/wp-content\/uploads\/2015\/09\/aspect_result.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-447 lazyload\" data-src=\"\/wp-content\/uploads\/2015\/09\/aspect_result.jpg\" alt=\"aspect_result\" width=\"712\" height=\"334\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2015\/09\/aspect_result.jpg 712w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2015\/09\/aspect_result-300x141.jpg 300w\" data-sizes=\"(max-width: 712px) 100vw, 712px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 712px; --smush-placeholder-aspect-ratio: 712\/334;\" \/><\/a><\/p>\n<p>G\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi <strong>GetProduct<\/strong> metot&#8217;u i\u00e7in eklemi\u015f oldu\u011fumuz <strong>Cache<\/strong> ve <strong>Log<\/strong> aspect&#8217;leri \u00e7al\u0131\u015fm\u0131\u015f bulunmaktad\u0131r. \u00d6z\u00fcnde yapm\u0131\u015f oldu\u011fumuz i\u015flemde GetProduct i\u00e7in business kodlar\u0131n\u0131n karma\u015f\u0131kla\u015fmas\u0131n\u0131 kesi\u015fen ilgilerimizi ay\u0131rarak sa\u011flam\u0131\u015f bulunmaktay\u0131z. Kod sat\u0131rlar\u0131 art\u0131k okunabilirli\u011fi y\u00fcksek bir seviyede ve kesi\u015fen ilgilerimiz tekrar kullan\u0131labilir haldedir.<\/p>\n<p>Aktaracaklar\u0131m \u015fimdilik bu kadar. Bu ba\u015fl\u0131k alt\u0131nda metotlar invoke olurken mutfakta neler olup bitiyor,\u00a0Interceptor&#8217;ler bu i\u015flemi nas\u0131l i\u015fliyor\u00a0gibi sorular\u0131da g\u00f6rm\u00fc\u015f olduk asl\u0131nda. AOP serisinin ilerleyen makalelerinde ise 3rd party k\u00fct\u00fcphaneler\u00a0arac\u0131l\u0131\u011f\u0131 bu i\u015flemleri nas\u0131l ger\u00e7ekle\u015ftirebiliriz konular\u0131nada de\u011finece\u011fim. \u00c7\u00fcnk\u00fc her zaman kendimiz custom olarak yazabilme ve i\u015fleyebilme olanaklar\u0131na sahip olamayabiliriz. Bunun en b\u00fcy\u00fck sebeplerinden birisi ise: standardizasyon. E\u011fer b\u00fcy\u00fck bir ekipte \u00e7al\u0131\u015f\u0131yorsan\u0131z baz\u0131 konular\u0131n \u00f6nemli oldu\u011fu gibi en b\u00fcy\u00fck unsurlardan biriside standardizasyondur.<\/p>\n<p>Bunun i\u00e7in gelecek makalelerimde\u00a0bu k\u00fct\u00fcphaneler\u00a0nas\u0131l kullan\u0131l\u0131yor konular\u0131nada de\u011finiyor olaca\u011f\u0131m. \u00d6rnek projeyi ekte bulabilirsiniz.<\/p>\n<p><a href=\"\/wp-content\/uploads\/2015\/09\/AOPGiris.rar\">AOPGiris<\/a><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Merhaba arkada\u015flar, bu\u00a0makalemde Aspect Oriented Programming (AOP) nedir\u00a0ve birbirleri ile kesi\u015fen ilgiler\u00a0(Cross-Cutting)\u00a0nelerdir gibi kavramlar\u0131 a\u00e7\u0131klayarak AOP serisine bir giri\u015f yapmak istiyorum. Uzun zamand\u0131r giri\u015f yapmay\u0131 d\u00fc\u015f\u00fcnd\u00fc\u011f\u00fcm bir konuydu asl\u0131nda AOP fakat\u00a0f\u0131rsat bulup bir t\u00fcrl\u00fc ba\u015flayamam\u0131\u015ft\u0131m. Umar\u0131m keyifli bir makale serisi \u00e7\u0131kar. :) AOP Nedir ve&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/gokhan-gokalp.com\/tr\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\/\">Devam\u0131n\u0131 okuyun<span class=\"screen-reader-text\">Aspect Oriented Programming (AOP) &#8211; Giri\u015f ve \u00d6rnek Bir Proje<\/span><\/a><\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[128],"tags":[130,129,131,17],"class_list":["post-443","post","type-post","status-publish","format-standard","hentry","category-aspect-oriented-programming-aop","tag-aop","tag-aspect-oriented-programming-aop","tag-interceptor","tag-transparent-proxy","entry"],"translation":{"provider":"WPGlobus","version":"3.0.2","language":"tr","enabled_languages":["en","tr"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"tr":{"title":false,"content":false,"excerpt":false}}},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Aspect Oriented Programming (AOP) - Giri\u015f ve \u00d6rnek Bir Proje - G\u00f6khan G\u00f6kalp<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/gokhan-gokalp.com\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Aspect Oriented Programming (AOP) - Giri\u015f ve \u00d6rnek Bir Proje - G\u00f6khan G\u00f6kalp\" \/>\n<meta property=\"og:url\" content=\"https:\/\/gokhan-gokalp.com\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\/\" \/>\n<meta property=\"og:site_name\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n<meta property=\"article:published_time\" content=\"2015-09-12T23:19:45+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2015-09-12T23:22:34+00:00\" \/>\n<meta name=\"author\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\\\/\"},\"author\":{\"name\":\"G\u00f6khan G\u00f6kalp\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"headline\":\"Aspect Oriented Programming (AOP) &#8211; Giri\u015f ve \u00d6rnek Bir Proje\",\"datePublished\":\"2015-09-12T23:19:45+00:00\",\"dateModified\":\"2015-09-12T23:22:34+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\\\/\"},\"wordCount\":1639,\"commentCount\":23,\"publisher\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"keywords\":[\"AOP\",\"Aspect Oriented Programming (AOP)\",\"Interceptor\",\"Transparent Proxy\"],\"articleSection\":[\"Aspect Oriented Programming (AOP)\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/gokhan-gokalp.com\\\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\\\/\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\\\/\",\"name\":\"Aspect Oriented Programming (AOP) - Giri\u015f ve \u00d6rnek Bir Proje - G\u00f6khan G\u00f6kalp\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#website\"},\"datePublished\":\"2015-09-12T23:19:45+00:00\",\"dateModified\":\"2015-09-12T23:22:34+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\\\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/gokhan-gokalp.com\\\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/gokhan-gokalp.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Aspect Oriented Programming (AOP) &#8211; Giri\u015f ve \u00d6rnek Bir Proje\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#website\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/\",\"name\":\"G\u00f6khan G\u00f6kalp\",\"description\":\"C# &amp; Python lover\",\"publisher\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/gokhan-gokalp.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\",\"name\":\"G\u00f6khan G\u00f6kalp\",\"pronouns\":\"he\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\",\"contentUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\",\"caption\":\"G\u00f6khan G\u00f6kalp\"},\"logo\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659\"},\"sameAs\":[\"https:\\\/\\\/gokhan-gokalp.com\"],\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/tr\\\/author\\\/gok-gokalp\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Aspect Oriented Programming (AOP) - Giri\u015f ve \u00d6rnek Bir Proje - G\u00f6khan G\u00f6kalp","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/gokhan-gokalp.com\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\/","og_locale":"tr_TR","og_type":"article","og_title":"Aspect Oriented Programming (AOP) - Giri\u015f ve \u00d6rnek Bir Proje - G\u00f6khan G\u00f6kalp","og_url":"https:\/\/gokhan-gokalp.com\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\/","og_site_name":"G\u00f6khan G\u00f6kalp","article_published_time":"2015-09-12T23:19:45+00:00","article_modified_time":"2015-09-12T23:22:34+00:00","author":"G\u00f6khan G\u00f6kalp","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"G\u00f6khan G\u00f6kalp","Tahmini okuma s\u00fcresi":"12 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/gokhan-gokalp.com\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\/#article","isPartOf":{"@id":"https:\/\/gokhan-gokalp.com\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\/"},"author":{"name":"G\u00f6khan G\u00f6kalp","@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"headline":"Aspect Oriented Programming (AOP) &#8211; Giri\u015f ve \u00d6rnek Bir Proje","datePublished":"2015-09-12T23:19:45+00:00","dateModified":"2015-09-12T23:22:34+00:00","mainEntityOfPage":{"@id":"https:\/\/gokhan-gokalp.com\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\/"},"wordCount":1639,"commentCount":23,"publisher":{"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"keywords":["AOP","Aspect Oriented Programming (AOP)","Interceptor","Transparent Proxy"],"articleSection":["Aspect Oriented Programming (AOP)"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/gokhan-gokalp.com\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/gokhan-gokalp.com\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\/","url":"https:\/\/gokhan-gokalp.com\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\/","name":"Aspect Oriented Programming (AOP) - Giri\u015f ve \u00d6rnek Bir Proje - G\u00f6khan G\u00f6kalp","isPartOf":{"@id":"https:\/\/gokhan-gokalp.com\/#website"},"datePublished":"2015-09-12T23:19:45+00:00","dateModified":"2015-09-12T23:22:34+00:00","breadcrumb":{"@id":"https:\/\/gokhan-gokalp.com\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/gokhan-gokalp.com\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/gokhan-gokalp.com\/aspect-oriented-programming-aop-giris-ve-ornek-bir-proje\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/gokhan-gokalp.com\/"},{"@type":"ListItem","position":2,"name":"Aspect Oriented Programming (AOP) &#8211; Giri\u015f ve \u00d6rnek Bir Proje"}]},{"@type":"WebSite","@id":"https:\/\/gokhan-gokalp.com\/#website","url":"https:\/\/gokhan-gokalp.com\/","name":"G\u00f6khan G\u00f6kalp","description":"C# &amp; Python lover","publisher":{"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/gokhan-gokalp.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe","name":"G\u00f6khan G\u00f6kalp","pronouns":"he","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659","url":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659","contentUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659","caption":"G\u00f6khan G\u00f6kalp"},"logo":{"@id":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776170659"},"sameAs":["https:\/\/gokhan-gokalp.com"],"url":"https:\/\/gokhan-gokalp.com\/tr\/author\/gok-gokalp\/"}]}},"_links":{"self":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/443","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/comments?post=443"}],"version-history":[{"count":9,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/443\/revisions"}],"predecessor-version":[{"id":455,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/443\/revisions\/455"}],"wp:attachment":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/media?parent=443"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/categories?post=443"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/tags?post=443"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}