﻿
{"id":12403,"date":"2019-11-06T05:37:30","date_gmt":"2019-11-06T05:37:30","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=12403"},"modified":"2019-11-06T05:37:30","modified_gmt":"2019-11-06T05:37:30","slug":"c-repository-design-patternrepository-tasarim-deseni","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/c-repository-design-patternrepository-tasarim-deseni\/","title":{"rendered":"C# Repository Design Pattern(Repository Tasar\u0131m Deseni)"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Bu i\u00e7eri\u011fimizde yaz\u0131l\u0131m projelerinde olmazsa olmaz bir tasar\u0131m kal\u0131b\u0131 olan Repository tasar\u0131m kal\u0131b\u0131n\u0131 inceliyor olaca\u011f\u0131z. Repository Design Pattern, veritaban\u0131 sorumlulu\u011funu \u00fcstlenen s\u0131n\u0131f\u0131 tasarlarken bir standart \u00fczerine oturtmay\u0131 hedefleyen ve Entity Framework gibi ORM(Object Relational Mapping) ara\u00e7lar\u0131yla kombine edilerek sorgusal anlamda az say\u0131da operatif metotla y\u00fcksek seviyede veri eri\u015fim imkan\u0131 sa\u011flayan bir strateji \u00fczerine kurulu tasar\u0131m desenidir. <\/p>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/11\/C-Repository-Design-PatternRepository-Tasar\u0131m-Deseni.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/11\/C-Repository-Design-PatternRepository-Tasar\u0131m-Deseni.png\" alt=\"C# Repository Design Pattern(Repository Tasar\u0131m Deseni)\" width=\"776\" height=\"300\" class=\"aligncenter size-full wp-image-12406\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/11\/C-Repository-Design-PatternRepository-Tasar\u0131m-Deseni.png 776w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/11\/C-Repository-Design-PatternRepository-Tasar\u0131m-Deseni-300x116.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/11\/C-Repository-Design-PatternRepository-Tasar\u0131m-Deseni-768x297.png 768w\" sizes=\"auto, (max-width: 776px) 100vw, 776px\" \/><\/a><\/p>\n<h3>\u00c7al\u0131\u015fma Mant\u0131\u011f\u0131<\/h3>\n<p>Yaz\u0131l\u0131m uygulamalar\u0131 genellikle yo\u011fun bir \u015fekilde veritaban\u0131 i\u015flemleri ger\u00e7ekle\u015ftiren ekosisteme sahip yap\u0131lar oldu\u011fundan dolay\u0131, ilgili uygulaman\u0131n herbir noktas\u0131nda gerekli veritaban\u0131 i\u015flemlerini tekrar tekrar yazmak yerine bu i\u015flemleri tekrar kullan\u0131labilirlik prensibi \u00e7er\u00e7evesinde daha pratik bir \u015fekilde tek seferde yapmam\u0131z\u0131 sa\u011flayan bir yap\u0131lanma geli\u015ftirmemiz gerekecektir. \u0130\u015fte bu yap\u0131lanma Repository s\u0131n\u0131f\u0131 olacakt\u0131r.<\/p>\n<p>Repository s\u0131n\u0131f\u0131, i\u00e7erisinde generic yap\u0131lanmalarla geli\u015ftirilen temel operasyonel veritaban\u0131 metotlar\u0131n\u0131 bar\u0131nd\u0131ran bir s\u0131n\u0131ft\u0131r. Yukar\u0131daki diyagramdan da g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere sorgu generate etme ve genellikle ORM ara\u00e7lar\u0131yla kombine edilerek veri e\u015fle\u015ftirme sorumlulu\u011funu \u00fcstlenmektedir. Bu yeteneklerini ana business sorumlulu\u011funu y\u00fcklenen s\u0131n\u0131flara kal\u0131t\u0131m yoluyla aktarmakta ve bu \u015fekilde kazand\u0131rmaktad\u0131r.<\/p>\n<h3>Uygulama Y\u00f6ntemi<\/h3>\n<p>Repository Design Pattern&#8217;i uygulayabilmek i\u00e7in \u00f6ncelikle t\u00fcm veritaban\u0131 i\u015flemlerini operatif olarak temsil edecek interface tan\u0131mlamam\u0131z gerekmektedir. Asl\u0131nda bu bir zorakilik de\u011fil, gelenektir. \u015e\u00f6yle konuya dair k\u0131sa bir ara\u015ft\u0131rma yaparsak, genellikle tasarlanan Repository s\u0131n\u0131f\u0131n\u0131n genel hatlar\u0131n\u0131n belirlenebilmesi i\u00e7in i\u00e7erisinde kullan\u0131lacak t\u00fcm metotlar\u0131 bar\u0131nd\u0131ran bir interface ile imzaland\u0131\u011f\u0131 g\u00f6zlenmektedir. K\u0131saca bu bizim \u00e7al\u0131\u015fmam\u0131z\u0131 kolayla\u015ft\u0131racak olan bir hamledir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public interface IRepository&lt;T&gt; where T : class\r\n    {\r\n        List&lt;T&gt; Get();\r\n        List&lt;A&gt; Get&lt;A&gt;() where A : class;\r\n        List&lt;T&gt; GetWhere(Expression&lt;Func&lt;T, bool&gt;&gt; metot);\r\n        List&lt;A&gt; GetWhere&lt;A&gt;(Expression&lt;Func&lt;A, bool&gt;&gt; metot) where A : class;\r\n        T GetSingle(Func&lt;T, bool&gt; metot);\r\n        A GetSingle&lt;A&gt;(Func&lt;A, bool&gt; metot) where A : class;\r\n        T GetById(int id);\r\n        A GetById&lt;A&gt;(int id) where A : class;\r\n        bool Add(T model);\r\n        bool Add&lt;A&gt;(A model) where A : class;\r\n        bool Remove(T model);\r\n        bool Remove&lt;A&gt;(A model) where A : class;\r\n        bool Remove(int id);\r\n        bool Remove&lt;A&gt;(int id) where A : class;\r\n        bool Update(T model, int id);\r\n        bool Update&lt;A&gt;(A model, int id) where A : class;\r\n        int Save();\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki kod blo\u011funa g\u00f6z atarsan\u0131z e\u011fer IRepository isimli bir interface tan\u0131mlanm\u0131\u015ft\u0131r ve i\u00e7erisine akl\u0131m\u0131za gelen t\u00fcm veritaban\u0131 i\u015flemlerini yapmam\u0131z\u0131 sa\u011flayacak olan metot imzalar\u0131 eklenmi\u015ftir. Burada dikkat edilmesi gereken iki husus vard\u0131r; birincisi, interface generic olarak tasarlanm\u0131\u015ft\u0131r&#8230;  Bunun nedeni, tasar\u0131mda kullan\u0131lacak tipi s\u00fcre\u00e7te geli\u015ftirici belirleyecektir ve t\u00fcm bu yap\u0131lanma belirtilen o tipe g\u00f6re geli\u015ftirilecektir. \u0130kinci husus ise geli\u015ftiricinin belirledi\u011fi tipin d\u0131\u015f\u0131ndaki t\u00fcrlerde yap\u0131lacak i\u015flemleri kar\u015f\u0131layabilmek i\u00e7in T tipinden ba\u011f\u0131ms\u0131z generic olarak tasarlanan metotlar geli\u015ftirilmi\u015ftir. Burada \u00f6rnek vermek gerekirse; &#8220;Araba&#8221; modelini kulland\u0131\u011f\u0131m\u0131z bir s\u0131n\u0131f i\u00e7erisinde &#8220;Surucu&#8221; modeline ait i\u015flem yapmam\u0131z gerekiyorsa e\u011fer i\u015fte burada generic metotlar devreye girecektir.<\/p>\n<p>Eee madem araba \u00fczerinden \u00f6rnek verdik ilgili Repository s\u0131n\u0131f\u0131m\u0131z\u0131 olu\u015ftururken bir ArabaContext nesnesi \u00fczerinde i\u015flem yapt\u0131\u011f\u0131n\u0131 varsayarak devam edelim. S\u0131rada tasarlad\u0131\u011f\u0131m\u0131z interface&#8217;i a\u015fa\u011f\u0131daki gibi Repository ismini verdi\u011fim generic bir s\u0131n\u0131fa uygulayarak concrete halini olu\u015fturuyorum. Bizler \u00f6rne\u011fimizi Web API uygulamas\u0131na uygun bir s\u0131n\u0131f ile ele almaktay\u0131z.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class Repository&lt;Type&gt; : ControllerBase, IRepository&lt;Type&gt; where Type : class\r\n    {\r\n        protected ArabaContext _arabaContext;\r\n        public Repository(ArabaContext arabaContext)\r\n        {\r\n            _arabaContext = arabaContext;\r\n        }\r\n        &#x5B;NonAction]\r\n        public DbSet&lt;Type&gt; Table()\r\n        {\r\n            return Table&lt;Type&gt;();\r\n        }\r\n        &#x5B;NonAction]\r\n        public DbSet&lt;A&gt; Table&lt;A&gt;() where A : class\r\n        {\r\n            return _arabaContext.Set&lt;A&gt;();\r\n        }\r\n        &#x5B;NonAction]\r\n        public bool Add(Type model)\r\n        {\r\n            return Add&lt;Type&gt;(model);\r\n        }\r\n        &#x5B;NonAction]\r\n        public bool Add&lt;A&gt;(A model) where A : class\r\n        {\r\n            Table&lt;A&gt;().Add(model);\r\n            Save();\r\n            return true;\r\n        }\r\n        &#x5B;NonAction]\r\n        public List&lt;Type&gt; Get()\r\n        {\r\n            return Get&lt;Type&gt;();\r\n        }\r\n        &#x5B;NonAction]\r\n        public List&lt;A&gt; Get&lt;A&gt;() where A : class\r\n        {\r\n            return Table&lt;A&gt;().ToList();\r\n        }\r\n        &#x5B;NonAction]\r\n        public Type GetById(int id)\r\n        {\r\n            return GetById&lt;Type&gt;(id);\r\n        }\r\n        &#x5B;NonAction]\r\n        public A GetById&lt;A&gt;(int id) where A : class\r\n        {\r\n            return GetSingle&lt;A&gt;(t =&gt; typeof(A).GetProperty(&quot;Id&quot;).GetValue(t).ToString() == id.ToString());\r\n        }\r\n        &#x5B;NonAction]\r\n        public bool Remove(Type model)\r\n        {\r\n            return Remove&lt;Type&gt;(model);\r\n        }\r\n        &#x5B;NonAction]\r\n        public bool Remove&lt;A&gt;(A model) where A : class\r\n        {\r\n            Table&lt;A&gt;().Remove(model);\r\n            return true;\r\n        }\r\n        &#x5B;NonAction]\r\n        public bool Remove(int id)\r\n        {\r\n            return Remove&lt;Type&gt;(id);\r\n        }\r\n        &#x5B;NonAction]\r\n        public bool Remove&lt;A&gt;(int id) where A : class\r\n        {\r\n            A silinecekData = GetSingle&lt;A&gt;(x =&gt; (int)typeof(A).GetProperty(&quot;Id&quot;).GetValue(x) == id);\r\n            Remove&lt;A&gt;(silinecekData);\r\n            Save();\r\n            return true;\r\n        }\r\n        &#x5B;NonAction]\r\n        public int Save()\r\n        {\r\n            return _arabaContext.SaveChanges();\r\n        }\r\n        &#x5B;NonAction]\r\n        public bool Update(Type model, int id)\r\n        {\r\n            return Update&lt;Type&gt;(model, id);\r\n        }\r\n        &#x5B;NonAction]\r\n        public bool Update&lt;A&gt;(A model, int id) where A : class\r\n        {\r\n            A guncellenecekNesne = GetById&lt;A&gt;(id);\r\n            var tumPropertyler = typeof(A).GetProperties();\r\n            foreach (var property in tumPropertyler)\r\n                if (property.Name != &quot;Id&quot;)\r\n                    property.SetValue(guncellenecekNesne, property.GetValue(model));\r\n            Save();\r\n            return true;\r\n        }\r\n        &#x5B;NonAction]\r\n        public List&lt;Type&gt; GetWhere(Expression&lt;Func&lt;Type, bool&gt;&gt; metot)\r\n        {\r\n            return GetWhere&lt;Type&gt;(metot);\r\n        }\r\n        &#x5B;NonAction]\r\n        public List&lt;A&gt; GetWhere&lt;A&gt;(Expression&lt;Func&lt;A, bool&gt;&gt; metot) where A : class\r\n        {\r\n            return Table&lt;A&gt;().Where(metot).ToList();\r\n        }\r\n        &#x5B;NonAction]\r\n        public Type GetSingle(Func&lt;Type, bool&gt; metot)\r\n        {\r\n            return GetSingle&lt;Type&gt;(metot);\r\n        }\r\n        &#x5B;NonAction]\r\n        public A GetSingle&lt;A&gt;(Func&lt;A, bool&gt; metot) where A : class\r\n        {\r\n            return Table&lt;A&gt;().FirstOrDefault(metot);\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki kod blo\u011funu incelerseniz e\u011fer Repository isminde bir s\u0131n\u0131f olu\u015fturulmu\u015ftur ve biraz \u00f6nce olu\u015fturdu\u011fumuz IRepository isimli interfaceden t\u00fcretilmi\u015ftir. Implementasyon neticesinde olu\u015fturulan operatif metotlar\u0131n i\u00e7eri\u011fine g\u00f6z atarsan\u0131z e\u011fer isimlerine uygun i\u015flevler ger\u00e7ekle\u015ftirilmekte ve gerekti\u011fi zaman reflection dahi kullan\u0131lmaktad\u0131r ve b\u00f6ylece T yahut A tipine belirtilen t\u00fcre g\u00f6re uygun tabloda i\u015flemler ger\u00e7ekle\u015ftirilmektedir.<\/p>\n<p><em><strong>Peki, T ve A t\u00fcrlerinin ne oldu\u011funu biliyor muyuz?<\/strong><\/em><br \/>\nHay\u0131r bilmiyoruz.<br \/>\n<em><strong>\u00d6yleyse t\u00fcr\u00fcn belli olmad\u0131\u011f\u0131(opsiyonel) bu durumda hangi tabloda \u00e7al\u0131\u015f\u0131laca\u011f\u0131n\u0131 nereden anl\u0131yoruz?<\/strong><\/em><br \/>\nContext nesnemizin Set metodu bizlere generic olarak belirtilen t\u00fcre uygun tabloyu getirmektedir. Dolay\u0131s\u0131yla yukar\u0131da &#8220;Table&#8221; ismindeki metot\/lar verilen T yahut A t\u00fcr\u00fcne uygun DbSet nesnesini(dolay\u0131s\u0131yla tabloyu) getirmekte ve bizlerde ona g\u00f6re i\u015flemler ger\u00e7ekle\u015ftirmekteyiz. En iyisi bunu deneyimleyip, g\u00f6rmenizdir&#8230; Ayr\u0131ca t\u00fcm metotlar\u0131n [NonAction] attributeu ile i\u015faretlenmesi sizi \u015fa\u015f\u0131rtmas\u0131n. Nihayetinde \u00f6rneklendirme bir API alt yap\u0131s\u0131 \u00fczerinden oldu\u011fu i\u00e7in ilgili metotlar\u0131n endpoint olmad\u0131\u011f\u0131n\u0131 ifade etmi\u015f oluyor ve d\u0131\u015far\u0131dan gelecek isteklerin es kasa bu metotlar taraf\u0131ndan kar\u015f\u0131lanmas\u0131n\u0131 engellemi\u015f oluyoruz.<\/p>\n<p>Evet, \u015fimdi olu\u015fturdu\u011fumuz Repository s\u0131n\u0131f\u0131n\u0131 kullanal\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    &#x5B;ApiController]\r\n    &#x5B;Route(&quot;api\/&#x5B;controller]&quot;)]\r\n    public class ArabaController : Repository&lt;Araba&gt;\r\n    {\r\n        public ArabaController(ArabaContext arabaContext) : base(arabaContext)\r\n        {\r\n        }\r\n\r\n        public bool Ekle(Araba araba)\r\n        {\r\n            return Add(araba);\r\n        }\r\n        public bool Sil(int id)\r\n        {\r\n            return Remove(id);\r\n        }\r\n        public List&lt;Araba&gt; TumArabalar()\r\n        {\r\n            return Get();\r\n        }\r\n    }\r\n<\/pre>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere Repository s\u0131n\u0131f\u0131m\u0131z ba\u015far\u0131l\u0131 bir \u015fekilde ilgili controller s\u0131n\u0131f\u0131nda kullan\u0131lmaktad\u0131r. Tabi burada &#8220;ArabaController&#8221; s\u0131n\u0131f\u0131na gelen istekler neticesinde ilgili endpointler tetiklenecek Repository metotlar\u0131 kullan\u0131lm\u0131\u015f olacakt\u0131r.<\/p>\n<p>Ayr\u0131ca burada \u015fu \u015fekilde de bir kullan\u0131m sergilenebilmektedir.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/11\/C-Repository-Design-PatternRepository-Tasar\u0131m-Deseni-1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/11\/C-Repository-Design-PatternRepository-Tasar\u0131m-Deseni-1.png\" alt=\"C# Repository Design Pattern(Repository Tasar\u0131m Deseni)\" width=\"1399\" height=\"311\" class=\"aligncenter size-full wp-image-12434\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/11\/C-Repository-Design-PatternRepository-Tasar\u0131m-Deseni-1.png 1399w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/11\/C-Repository-Design-PatternRepository-Tasar\u0131m-Deseni-1-300x67.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/11\/C-Repository-Design-PatternRepository-Tasar\u0131m-Deseni-1-768x171.png 768w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/11\/C-Repository-Design-PatternRepository-Tasar\u0131m-Deseni-1-1024x228.png 1024w\" sizes=\"auto, (max-width: 1399px) 100vw, 1399px\" \/><\/a><br \/>\nB\u00f6ylece Repository&#8217;den t\u00fcreyen herbir s\u0131n\u0131f\u0131n instance&#8217;i \u00fczerinden de veritaban\u0131 i\u015flemlerini y\u00fcr\u00fctebilirsiniz.<\/p>\n<p>Son s\u00f6z olarak nihai usule uygun kelam etmemiz gerekirse Repository Design Pattern ORM yap\u0131lanmalar\u0131yla(\u00f6zellikle Entity Framework) olduk\u00e7a basit ve bir o kadar etkili veritaban\u0131 havuzu olu\u015fturmam\u0131z\u0131 ve t\u00fcm i\u015flemleri tek kalemde halletmemizi sa\u011flayan g\u00fczel ve kullan\u0131\u015fl\u0131 bir tasar\u0131m desenidir.<\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Bu i\u00e7eri\u011fimizde yaz\u0131l\u0131m projelerinde olmazsa olmaz bir tasar\u0131m kal\u0131b\u0131 olan Repository tasar\u0131m kal\u0131b\u0131n\u0131 inceliyor olaca\u011f\u0131z. Repository Design Pattern, veritaban\u0131 sorumlulu\u011funu \u00fcstlenen s\u0131n\u0131f\u0131 tasarlarken bir standart \u00fczerine oturtmay\u0131 hedefleyen ve Entity Framework gibi ORM(Object&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":12406,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[153],"tags":[750,3051,3052,1115],"class_list":["post-12403","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-design-pattern","tag-design-pattern","tag-repository-design-pattern","tag-repository-tasarim-deseni","tag-tasarim-desenleri"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/12403","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=12403"}],"version-history":[{"count":33,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/12403\/revisions"}],"predecessor-version":[{"id":12438,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/12403\/revisions\/12438"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/12406"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=12403"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=12403"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=12403"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}