14 Aralık 2020 Pazartesi
Docker Container Yapısı -3
Bu yazıda Docker Container yapısında yer alan Docker CLI kullanımına, komutlarına ve bilmemiz gerek temel özelliklere değinmeye devam edeceğim.
Docker Container Yapısı -1 ve Docker Containe Yapısı -2 yazılarında bir container oluşturup çalıştırdık ve ona ne yapmasını söylediysek onu yaptı. Container'ın ideal kullanımında da senaryo bu şekilde ilerler. Yani container'ı çalıştırırsınız ve container çalıştırıldığı image dosyasında ki ayarlara göre ayağa kalkar. Başka bir deyişle container çalıştıktan sonra içine girip şunu çalıştır bunu çalıştır demeyiz. Bu işlemlerin tamamı container image oluşturma aşamasında belirtilir ve image olarak paketlenir. Container ise o image den oluşturulmuş çalışan bir kopyadır. Genel olarak tek bir uygulama çalışması için hazırlanır ve container çalıştırıldığı zaman da o uygulama çalışır ve uygulama çalıştıkça da container ayakta durmaya devam eder.
Kısaca bir container hangi uygulamanın çalışması için ayarlandıysa onunla ilgili her türlü ayarın image oluşturma aşamasında ayarlanmasıdır. Dolayısıyla sonradan container'a bağlanıp herhangi bir değişiklik yapmak gerekmez.
Container'a bağlanıp herhangi bir değişiklik yapmamız gerekmez demek container'a bağlanamayız anlamına gelmemektedir. Docker, container'ın içine bağlanıp değişiklikler yapmamıza izin verir. Bunun için gerekli tek şey o container image sinin içerisinde bağlanabileceğimiz bir shell olmasıdır ki hemen hemen bütün image'lerde bağlanabileceğimiz bir shell mevcuttur.
Container'a Bağlanma:
Öncelikle bir container oluşturalım:
docker container run -d -p 8282:80 --name htmlcontainer emrahakin/htmlsite
container oluşturma kısmını bir önce ki yazıda detaylı olarak anlatmıştım dilerseniz orayı referans alabilirsiniz.
Container'ımızı oluşturduktan sonra çalışan container'ları listeleyelim
docker container ls
Bu oluşturduğumuz container'a bağlanmak için "exec" komutunu kullanacağız.
docker container exec -it CONTAINER ID sh
Gördüğünüz gibi "sh" komutu ile container içerisinde ki shell'e bağlanmış olduk. Ben Docker imege oluştururken alpine tabanlı bir docker image si oluşturdum. Alpine tabanlı dağıtımlarda "sh" ile bir shell açabiliyorum.
Eğer Ubuntu tabanlı bir image kullansaydım onun içinde bash olduğundan "sh" yerine "bash" yazacaktım.
docker container exec -it CONTAINER ID bash
Peki "-it" nedir?
-it esasında iki opsiyonun birleşimi "--interactive" ve "--tty" opsiyonlarının birleşimi olarak "-it" kullanıyoruz. Yani bu container'a interactive modda bağlan (benim komutlarımı bu container içerisinde çalıştır) ve bunu sağlamak içinde bir terminal bağlantısı kur demek.
Container'a bağlandığımıza göre artık normal bir Linux makine gibi ne yapmak istiyorsak onu yapabiliriz.
Mesela bağlandığımız container'da ki dosyaları "ls" komutu ile listeleyelim
Container'ımızı ayağa kaldırdığımız makinede bir web browser açık localhost:8282 adresine gidersek orada bir web sitesinin çalıştığını göreceğiz.
Şimdi "sh" ile container'ın içine bağlandığımıza göre bu html sayfasını değiştirebilirim.
Docker imnage sini oluştururken bir Dockerfile dosyası hazırlamıştık bu dosyaya buradan ulaşabilirsiniz. Bu Dockerfile dosyasında index.html in /usr/share/ngnix/html klasörü içerisine atılmasını belirtmiştik. Şimdi bu dizine bağlanarak index.html dosyası orada mı bir bakalım.
Bu şekilde tek satır komutla da ilgili klasöre gidebiliriz:
cd usr/share/ngnix/html
Artık index.html dosyasına ulaştığımıza göre değiştirebiliriz:
echo "yeni yazı ekledim" >> index.html
bu komutu çalıştırdığımızda mevcut index.html dosyasına "yeni yazı ekledim" diye bir text eklemiş olacağız.
Web tarayıcımızda sayfayı yenilediğimizde "yeni yazı eklendi" yazısının sayfaya eklendiğini görüyoruz.
Görüldüğü gibi mevcut bir docker container'ın içine girip değişiklik yapabiliyoruz.
Bu container'ın içinde hangi uygulamaların çalıştığını yine "ps" komutuyla görebiliriz. Container'ın içindeyken terminal ekranına "ps" komutunu yazarsak hangi uygulamaların çalıştığı listelecektir.
"exit" komutuyla container'ın içerisinden çıkıp kendi shell ekranımıza dönebiliriz. "exit" komutu ile sadece container ile olan bağlantımızı kesiyoruz container çalışmaya devam eder bunu da "docker container ls" komutuyla görebiliriz.
Docker Container Yapısı -2

Bu yazıda Docker Container yapısında yer alan Docker CLI kullanımına, komutlarına ve bilmemiz gerek temel özelliklere değinmeye devam edeceğim. Dilerseiz buradan Docker Container hakkında ki ilk yazıma ulaşabilirsiniz.
Ben örnek olması açısından Docker Hub üzerinde, içinde nginx ve html olan bir image oluşturdum. Bu yazımda bu image üzerinden ilerleyeceğim. Docker Hub üzerinde image oluşturma kısmına ileride detaylı olarak değineceğim.
Oluşturduğum bu docker image'sinden bir container oluşturduğumuzda localhost' umuzda nginx üzerinde çalışan bir html web sayfası ayağa kalkacak ve yayına başlayacak. Bu docker container'ı oluşturan Dockerfile dosyasını incelemek isterseniz buradan ulaşabilirsiniz.
Container'ı oluşturarak işle başlayalım:
docker container run -d -p 8282:80 --name htmlcontainer emrahakin/htmlsite
Not: burada kullandığımız -p komutu port anlamına geliyor. Container'ımızı istediğimiz bir porttan ayağa kaldırabiliriz ben 8282 portunu kullandım. -d komutu ise container'ımızı detach mode (arka planda çalıştırmak) ile çalıştıracağımızı belirtir. Bu komutlara ileride detaylı olarak değineceğim.
Uygulamamızı ayağa kaldırdıktan sonra terminal satırına aşağıda ki kodu yazarsak çalışan containerlarımızı listelemiş oluruz.
docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
21ba7d5780ca emrahakin/htmlsite "/docker-entrypoint.…" 14 minutes ago Up 3 minutes 0.0.0.0:8282->80/tcp htmlcontainer
Ekran çıktısında, emrahakin/htmlsite image'sinden türeyen, htmlcontainer adında bir container'ın 3 dakikadır ayakta olduğunu görüyoruz.
Bu container içerisinde bir nginx server çalıştığı için, container oluşturulduktan sonra çalışmasına devam ediyor. Bir önce ki yazıda olduğu gibi tek sefer çalışan bir uygulama yerine devamlı çalışan bir web uygulaması ayağa kaldırmış olduk.
Şuan da docker'ın yüklü olduğu makinede (localhost) bir web tarayıcı açıp adres olarak localhost:8282 yazarsanız karşınıza aşağıda ki sayfa gelecektir.
Peki makinemizde bir nginx server yüklü değilken bu html sayfa nasıl çalıştı?
Esasında bu sorunun cevabı neden docker kullanıyoruz ile aynı. Çünkü biz container'ımızı içinde nginx yüklü olan ve bu nginx server da html sayfa çalıştıran bir docker image den oluşturduk.
"docker container ls" komutu ile çalışan container'larımızı listelediğimiz zaman her biine bir CONTAINER ID atadığını görürüz. Bu CONTAINER ID bizim ilgili container üzerinde işlem yapabilmemiz için docker tarafından atanan Unique ID lerdir.
Mesela bu container'ın loglarını görmek istersek:
docker container logs CONTAINER ID (bende 21ba7d5780ca)
CONTAINER ID sinin tamamını yazmanıza gerek yok ilk 4 hanesi de size istediğiniz sonucu verecektir.
docker container logs 21ba
Container Durdurmak:
stop komutu ile çalışan bir container'ı durdurabiliriz:
docker container stop 21ba
"docker container ls" komutunu çalıştırdığımızda container'ımızın artık bu listede olmadığını görebiliriz. "docker container ls" komutu sadece çalışan container'ları listeler. Containerlarımızın tamamını görmek istiyorsak "docker container ls -a" komutu ile listeleme yapmalıyız.
docker container ls -a
Bu komutu çalıştırdığımızda docker engine içinde yer alan çalışan ve durdurulmuş tüm containerların listesini görebiliriz.
Container Çalıştırmak:
start komutu ile durdurulmuş bir container'ı aynı özellikleriyle yeniden çalıştırabilriz:
docker container start CONTAINER ID (bende 21ba)
duran container'ımızı yeniden çalıştırdıktan sonra "docker container ls" komutuyla yeniden çalışan containerlar listesinde container'ımızı görebiliriz.
Container Silmek:
Container'ı durdurmak ile silmek aynı şey değildir. Eğer zaten durdurulmuş bir container'ı silmek istiyorsak:
docker container rm CONTAINER ID (bende 21ba)
Eğer çalışan bir container'ı silmek istiyorsak: Burada iki opsiyonumuz bulunmakta önce çalışan container'ı "stop" komutu ile durdurabilir ardından silebiliriz yada çalışır vaziyette iken
docker container rm -f CONTAINER ID (bende 21ba)
komutuyla silebiliriz. -f burada force anlamına gelmektedir.
Aynı anda birden fazla container'ı da silebiliriz bunun için "docker container rm" komutundan sonra silinmesini istediğimiz containerların ID lerini aralarında boşluk bırakarak yazmamız yeterli olacaktır.
docker container rm CONTAINER ID1 CONTAINER ID2 CONTAINER ID3 ...
7 Aralık 2020 Pazartesi
CentOS 7'de VirtualBox Nasıl Kurulur
Şu komutu kullanarak mevcut CentOS 7 kurulumunu güncelleyerek sisteminizi hazırlayın:
sudo yum update
Adım 1: vboxdrv Kernel Module'ü kurun
VirtualBox, konuk işletim sistemleri için fiziksel belleği kontrol etmek ve tahsis etmek için vboxdrv çekirdek modülünü kullanır.
Ek modüller (kernel-devel, dkms, kernel-headers, wget ve diğer bağımlılık paketleri) kurmak için şunu girin:
sudo yum install –y patch gcc kernel-headers kernel-devel make perl wget
Kurulum tamamlandığında, yeni çekirdeği kullanmaya başlamak için sisteminizi yeniden başlatın:
sudo reboot
Adım 2: VirtualBox Deposunu İndirin
VirtualBox Oracle deposunu indirmek için şunu girin:
sudo wget http://download.virtualbox.org/virtualbox/rpm/el/virtualbox.repo -P /etc/yum.repos.d
Komut, depo dosyasını indirir ve /etc/yum.repos.d dizinine yerleştirir.
3. Adım: VirtualBox'ı kurun
VirtualBox'ı indirilen depodan kurun: (Ben yazıyı hazırlarken son sürüm 6.1 olduğundan. Ben VirtualBox 6.1 kurulumu üzerinden gideceğim)
sudo yum install VirtualBox-6.1
Sistem sizden GPG anahtarını kabul etmenizi ister. Onaylamak için Y girin.
Kurulum tamamlandıktan sonra, VirtualBox Linux çekirdek modülü hizmetinin durumunu kontrol edin:
sudo systemctl status vboxdrv
Terminal çıktısı, hizmetin etkin olduğunu doğrular ve bir zaman damgası sağlar.
Adım 4: Oracle VirtualBox Extension Pack'i Kurun (İsteğe Bağlı)
USB kullanımı, uzak masaüstü protokolleri veya disk şifreleme gibi işlevler için ek paketlerin ayrıca yüklenmesi gerekir.
VirtualBox paketini indirmek için şunu girin: (Ben yazıyı hazırladığımda Virtualbox 6.16 sürümü en güncel sürüm olduğundan örnek kodumu 6.16 üzerinden oluşturdum.)
wget http://download.virtualbox.org/virtualbox/6.1.16/Oracle_VM_VirtualBox_Extension_Pack-6.1.16.vbox-extpack
Terminal ekranından, paketlerin indirildiğini görebiliriz.
Ardından, paketi VirtualBox'a aktarın:
sudo VBoxManage extpack install Oracle_VM_VirtualBox_Extension_Pack-6.1.16.vbox-extpack
Y ile hüküm ve koşulları kabul ettiğinizi onaylayın. Sistem, uzantı paketinin başarıyla kurulduğunu onaylar.

Adım 5: VirtualBox'ı Başlatın
Yeni kurulan VirtualBox'a erişmek için şu komutu kullanın:
VirtualBox
Not:
Virtualbox'ı Centos7 sisteminden kaldırmak isterseniz şu komutu kullanabilirsiniz: (ilgili komut sayfası)
Virtualbox'ı Centos7 sisteminden kaldırmak isterseniz şu komutu kullanabilirsiniz: (ilgili komut sayfası)
sudo yum erase *VirtualBox*
16 Kasım 2020 Pazartesi
Docker Container Yapısı -1
Bu yazıda Docker Container yapısında yer alan Docker CLI kullanımına, komutlarına ve bilmemiz gerek temel özelliklere değinmeye çalışacağım.
Docker CLI (Command Line Interface): Bir docker kurulumu yaptığımızda sisteme yüklenen ve o Docker Engine yi yönetmemizi sağlayan komut satırı ara yüzüdür.
terminal satırına aşağıda ki komutu yazarak makinemizde kurulu olan docker engine hakkında bilgileri görelim:
docker info
komut çalıştırıldığında, makinemizde kurulu olan docker engine hakkında ki bilgileri ekrana yazar.
Çıktıda göreceğimiz gibi mevcutta kaç containerımız var, bu containerların kaç tanesi çalışıyor kaç tanesi durmuş durumda gibi temel bilgilere docker info komutu ile ulaşabiliriz.
Docker içinde kullanabileceğimiz bütün komutlara erişmek için komut satırına "docker" yazmamız yeterli olacaktır
docker
Terminal satırına "docker" komutunu yazıp çalıştırırsak Docker içinde kullanabileceğimiz bütün komutları görmüş oluruz.
Ekran çıktısında Management Commands ve Commands başlıkları altında kullanabileceğimiz komut formatlarını görebiliriz.
Docker ilk ortaya çıktığında komut satırı docker command ( docker run hello-world gibi) şeklindeydi. Bu kullanım Docker'ın geriye dönük uyumlu olamak istemesinden hala çalışıyor.
Docker geliştikçe ve daha kompleks işlemler yapmaya başladıkça komut satırını üç kademeli bir yapıya geçirdi. Bu nedenle hemen hemen her Command kendi Management komutuna sahip oldu. Bu üç kademeli yapıyı da docker management-command command( docker conntainer run hello-world ) şeklinde yapılandırdı.
Kısacası Docker da hangi Management Command ile işlem yapmak istiyorsak önce onu yazıyoruz ardından Command komutunu yazıyoruz. Bu kısımda bütün komutları ezberlememize tabi ki olanak yok. Ezberlemeye çalışmak yerine --help yardım komutunu kullanmak bizim için daha faydalı olacaktır. Mesela "image" lerle ilgili bir işlem yapmak istiyoruz, terminal satırına docker image --help komutunu yazalım.
docker image --help
Ekran çıktısından da gördüğünüz gibi image Management Commands'ı ile yapabileceğimiz komutlar karşımıza çıkıyor. Örnek olarak bir tane image silmek istiyorsak. Commands lara baktığımızda silme komutunun "rm" olduğunu görüyoruz. Peki "docker image rm" komutunu nasıl kullancağız?
Komut satırına "docker image rm --help" yazarsak image içinde "rm" i nasıl kullanabileceğimizi bize gösterecektir.
En üstte gördüğümüz gibi docker image rm [OPTIONS] IMAGE [IMAGE...] yapısıyla image management-commands' ını kullanabiliyoruz.
Örnek olarak:
docker image rm -f hello-world
Docker Container:
Bir docker container'ı nasıl oluşturacağımızı komut satırına "--help" fonksiyonu ile öğrenelim.
docker container --help
Ekran çıktısını incelediğimizde "create" komutu bir container oluşturmamızı, "start" komutu ise o container'ı başlatmamızı sağlıyor.
Her defasında önce container'ı oluşturup sonra start ile çalıştırmak yerine "run" komutunu da kullanabiliriz. Bu komut (run) yukarıda da açıklandığı gibi container yoksa önce oluşturuyor sonra da çalıştırıyor.
Peki docker container run komutunu nasıl kullanacağız?
docker container run --help
Bu komutu yazdığınızda karşınıza uzunca bir liste çıkacaktır. Bu listeyi inceleyip farklı komutlar kullanabilirsiniz. Ben örnek olması amacıyla "run" komutunu inceleyeceğim.
Ekran çıktısında önemli olan kısım Usage kısmıdır. Docker, Usage kısmında bu komutu nasıl kullanacağımızı bize söylüyor.
"Usage: docker container run [OPTIONS] IMAGE [COMMAND] [ARG...]"
docker container run daha sonra girmek istediğim bir "OPSIONS" varsa bunu yazıyorum sonra hangi "IMAGE" den bir container yaratmak istiyorsam o image'nin adını giriyorum en son olarak ta bu image içinde farklı bir komut çalıştırmak istiyorsam o komutları giriyorum. Hadi deneyelim:
docker container run --name ilkcontainer emrahakin/ilkcontainer
Komut satırına aşağıda ki komutu yazdığımızda ilkcontainer adında emrahakin/ilkcontainer image sinden bir container oluşturacağız.
docker container run --name ilkcontainer emrahakin/ilkcontainer
Görüldüğü gibi docker run komutundan sonra emrahakin/ilkcontainer image si bizde olmadığı için önce docker hub dan bu image yi çekti ve ardından bu image den ilkcontainer isminde bir container oluşturdu ve container içerisinde ki uygulamayı çalıştırdı "Merhaba İlk Container Başarıyla Oluşturuldu" yazısını yazdı ve container kapatıldı.
https://github.com/emrakin/DockerLearningRepo/tree/main/CreateDockerImage/CreateDockerImage dilerseniz bu linkte ki Dockerfile dosyasını ve ilkcontainer olarak indirdiğimiz .NET Console Uygulamasını inceleyebilirsiniz.
docker container ls -a
Komut satırına docker container ls -a yazarsak sistemimizde oluşturulmuş bütün container ları görebiliriz. (-a yazmazsak sadece çalışan container ları görebiliriz.)
ilkcontainer isimli container a baktığınız da "STATUS" kısmında Exited (yani kapatılmış) yazdığını göreceksiniz. Kapatılmasının sebebini şöyle açıklayabiliriz.
Bir docker imajından container oluşturduğumuz zaman içinde varsayılan olarak çalışması için bir uygulama vardır. Bu uygulama çalıştığı sürece container ayakta kalır. Uygulama çalışmayı bıraktığı zaman container da kapanır. Bizim docker imajımızda yer alan uygulama da ekrana "Merhaba İlk Container Başarıyla Oluşturuldu" yazısını yazdıktan sonra kapandığı için ilkcontainer adında oluşturduğumuz container da Exited olmuş durumda. Yukarıda da bahsettiğim gibi ben burada bir .NET Console App uygulaması yaptım Dockerfile ve uygulamaya https://github.com/emrakin/DockerLearningRepo/tree/main/CreateDockerImage/CreateDockerImage bu linkten ulaşabilir ve inceleyebilirsiniz.
Bir sonra ki anlatımda container yapısına devam edeceğim ve bir web uygulamasının docker içinde nasıl çalıştırıldığından bahsedeceğim.
13 Mart 2020 Cuma
C# Dersleri 9 - Veri Tipleri : Enum Veri Tipi
Enum Veri Tipi
Enum, sabitlerle tanımlanmış ayırt edici bir veri tipidir. Enum kullanmanın en temel amacı, programlamada "magic string" denilen değerler tutmak yerine bir Enum sabiti ile bu değerleri getirmektir.
magic string nedir derseniz? Mesela
string gunler = "Salı";
gibi bir değişken tanımladığımızda burada ki "Salı" bir magic stringtir.
Eğer Günlerden birini getirmek istiyorsak bir Enum sabiti vasıtasıyla bunu yapabiliriz.
Örnek Uygulama:
Sali
1
1
Uygulamanın çıktısına baktığımızda "(int)Gunler.Salı" için "1" değerini verdiğini görüyoruz. Enum sabitleri de eğer bir tanımlama yapılmamışsa "Pazartesi=1 gibi" değerlerini sıfırdan başlatırlar.
Enum sabitlerinin "if" bloglarıyla kullanımı içinde bir örnek uygulama yazalım.
if bloglarına bir sonra ki yazıda değineceğiz fakat enum sabitlerini anlamamız için güzel bir örnek olacağını düşünüyorum
Örnek Uygulama:
Seçtiginiz Gün Haftasonu Günü Degildir
Github Adresi : https://github.com/emrakin/CSharpDersleri
Tüm Derslerin Listesi için Tıkla
C# Dersleri 8 - Veri Tipleri : Decimal Veri Tipi
Decimal Veri Tipi
Decimal veri tipleri 128 bitlik gerçek sayı değerleridir. Integer için long neyse double içinde decimal odur.
Decimal değişkeninde eğer tam sayı olmayan bir değer tutmak istiyorsak sayının sonuna M veya m harfini koymamız ve bu değerin bir decimal değişkeni olduğunu belirtmemiz gerekmektedir. Bunun sebebi C# ortamında ondalıklı sayıların varsayılan değeri double'dır.
Decimal değişkeninde bir tam sayı kullanacaksak sonuna bu M veya m harfini yazmamıza gerek yoktur.
Örnek Uygulama:
Örnek Çıktı:
Birinci sayi: 10
Ikinci sayi: 10.5
Üçüncü sayi: -10
Dördüncü sayi: -10.5
Maksimum deger: 79228162514264337593543950335
Minimum deger: -79228162514264337593543950335
Ikinci sayi: 10.5
Üçüncü sayi: -10
Dördüncü sayi: -10.5
Maksimum deger: 79228162514264337593543950335
Minimum deger: -79228162514264337593543950335
Github Adresi : https://github.com/emrakin/CSharpDersleri
Tüm Derslerin Listesi için Tıkla
12 Mart 2020 Perşembe
C# Dersleri 7 - Veri Tipleri : Double Veri Tipi
Double Veri Tipi
Double veri tipleri 64 bitlik gerçek sayı değerleridir. Double olarak tanımlanmış değişkenlerde tam sayılardan farklı olarak ondalıklı sayıları da tutabiliriz.
double deger = 10.4;
Örnek Uygulama:
Örnek Çıktı:
Birinci degisken: 243.14
Ikinci degisken: -1432
Maksimum deger: 1.7976931348623157E+308
Minimum deger: -1.7976931348623157E+308
Ikinci degisken: -1432
Maksimum deger: 1.7976931348623157E+308
Minimum deger: -1.7976931348623157E+308
Github Adresi : https://github.com/emrakin/CSharpDersleri
Tüm Derslerin Listesi için Tıkla
C# Dersleri 6 - Veri Tipleri : Char Veri Tipi
Char Veri Tipi
Char veri tip 16 bit uzunluğunda unicode standartlarında karakterlerin karşılığını tutan bir veri tipidir. Her karakterin unicode standartları çerçevesinde bir karşılığı bulunmaktadır ve char tipinde ki değişkene bir değer atandıktan sonra o değişken bir karakteri temsil etmektedir.Char veri tiplerine doğrudan karakter atayabilirsiniz.
char deger1 = 'A';Char veri tipine hexadecimal karakter karşılında değer atabilirsiniz.
char deger2 ='\x0058'Char veri tipine ASCII sayısal karşılığından Char tipine dönüşüm yapabilirsiniz.
char deger3 = (char)55;Char veri tipine Unicode karakter ataması yapabilirsiniz.
char deger4 = '\u0058';
Örnek Uygulama:
A
X
7
X
X
7
X
Github Adresi : https://github.com/emrakin/CSharpDersleri
Tüm Derslerin Listesi için Tıkla
C# Dersleri 5 - Veri Tipleri : Bool Veri Tipi
Bool Veri Tipi
Bool veri tipi "Doğru" veya "Yanlış" olmak üzere iki değer alabilen mantıksal bir veri tipidir. Daha çok kontrol işlemlerinde kullanılır.
bool dogru= true;İleri ki yazılarda şart ve kontrol bloklarını incelerken bool değişkenini bolca kullanacağız. Şimdilik sadece iki değer aldığınız ve bunları "True" veya "False" olduğunu bilmeniz yeterli olacaktır.
bool yanlis = false;
Örnek bir uygulama da bunu göstermek istersek. Mesela elimizde değeri 8 olan integer bir değişken olsun ve bunun 12 den büyük olup olmadığını kontrol edelim.
Örnek Uygulama:
Örnek Çıktısı:
False
sayi değişkenine atadığımız 8 değeri 12 sayısından küçük olduğu için sonuç "False" olarak döndü.
Son olarak bool veri tipinin de bir Değer Tipi olduğunu unutmayın.
Github Adresi : https://github.com/emrakin/CSharpDersleri
Tüm Derslerin Listesi için Tıkla
C# Dersleri 4 - Veri Tipleri : Byte Veri Tipi
Byte Veri Tipi:
Byte(byte) tam sayıları tuttuğumuz 8 bitlik veri depolayan bir değer tipidir.
Byte veri tipi 0 ile 255 arasında ki değerleri alabilir. Görüldüğü üzere eksi (negatif) bir tam sayı değeri alamaz.
Örnek Uygulama:
Byte veri tipi 0 ile 255 arasında ki değerleri alabilir. Görüldüğü üzere eksi (negatif) bir tam sayı değeri alamaz.
Örnek Uygulama:
Örnek Çıktı:
Ilk Sayi: 5
Ilk Sayi: 8
Max Sayi: 255
Min Sayi: 0
Ilk Sayi: 8
Max Sayi: 255
Min Sayi: 0
Github Adresi : https://github.com/emrakin/CSharpDersleri
Tüm Derslerin Listesi için Tıkla
C# Dersleri 3 - Veri Tipleri : Short Veri Tipi
Short Veri Tipi:
Short(short) tam sayıları tuttuğumuz 16 bitlik veri depolayan bir değer tipidir.
Integer ve Long veri tiplerine göre bellekte daha az yer kaplarlar ve değer aralıkları da daha küçüktür. Short veri tipi -32768 ile 32767 arasında ki değerleri alabilir.
short ilknumara = 10;
Örnek Uygulama:
Örnek Çıktı:
Ilk Sayi: 10
Ilk Sayi: -15
Max Sayi: 32767
Min Sayi: -32768
Ilk Sayi: -15
Max Sayi: 32767
Min Sayi: -32768
Github Adresi : https://github.com/emrakin/CSharpDersleri
Tüm Derslerin Listesi için Tıkla
11 Mart 2020 Çarşamba
C# Dersleri 2 - Veri Tipleri : Long Veri Tipi
Long Veri Tipi:
Bir önce ki yazı da Integer Veri Tipini öğrendik ve -2147483648 ile 2147483647 arasında değer alabileceğini belirttik. Peki kullanmak istediğim değer bu sayı değerlerinin arasında yer almıyorsa ne yapmalıyız?
Bu tarz durumlarda integer veri tipinden daha büyük aralığa sahip"long" veri tipini kullanabiliriz. Long veri tipi integer veri tipinin aldığı her değeri alabilir.
long ilknumara = 2147483647 ;Burada aklınıza şu soru gelebilir. Madem long veri tipi integer veri tipinin aldığı tüm değerleri ve daha fazlasını alabiliyor o zaman neden integer kullanayım her değişkeni long tanımlarım.
Long veri tipi 64 bitlik veri depolamasından dolayı bellek üzerinde kapladığı alan integer veri tipinden büyüktür. Bu bakımdan zorunlu kalınmadıkça (integer ihtiyacımızı karşılıyorsa) long veri tipini kullanmak bellek üzerinde fazladan bir alan kaybına neden olacaktır.
Bellekte ayrılan alanın, tuttuğumuz değerle bir alakası yoktur, değer tipimizle bir alakası vardır. Bu bakımdan long veri tipinde değeri 15 olan bir değişkeni tutmak istediğimizde kullandığımız bellek alanı ile int veri tipinde değeri 15 olan bir değişkeni tutmak istediğimizde kullandığımız bellek alanı arasında fark vardır.
Bu bakımdan integer ihtiyacımızı karşılıyor iken long veri tipini tutmamızın bir anlamı yoktur.
Örnek Uygulama:
static void Main(string[] args)
{
long ilknumara = 92233720368547;
long ikincinumara = -92233720368547;
Console.WriteLine("İlk Sayı: {0}", ilknumara);
Console.WriteLine("İkinci Sayı: {0}", ikincinumara);
Console.ReadLine();
}
{
long ilknumara = 92233720368547;
long ikincinumara = -92233720368547;
Console.WriteLine("İlk Sayı: {0}", ilknumara);
Console.WriteLine("İkinci Sayı: {0}", ikincinumara);
Console.ReadLine();
}
Uygulama Çıktısı:
Ilk Sayi: 92233720368547
Ikinci Sayi: -92233720368547
Ikinci Sayi: -92233720368547
Long veri tipinin değer aralığı –9,223,372,036,854,775,808 ile 9,223,372,036,854,775,807 arasındadır.
Örnek Uygulama:
static void Main(string[] args)
{
long ilknumara = 92233720368547;
long ikincinumara = -92233720368547;
long maxdeger = 9223372036854775807;
long mindeger = -9223372036854775808;
Console.WriteLine("İlk Sayı: {0}", ilknumara);
Console.WriteLine("İkinci Sayı: {0}", ikincinumara);
Console.WriteLine("Max Sayı: {0}",maxdeger);
Console.WriteLine("Min Sayı: {0}",mindeger);
Console.ReadLine();
}
{
long ilknumara = 92233720368547;
long ikincinumara = -92233720368547;
long maxdeger = 9223372036854775807;
long mindeger = -9223372036854775808;
Console.WriteLine("İlk Sayı: {0}", ilknumara);
Console.WriteLine("İkinci Sayı: {0}", ikincinumara);
Console.WriteLine("Max Sayı: {0}",maxdeger);
Console.WriteLine("Min Sayı: {0}",mindeger);
Console.ReadLine();
}
Uygulama Çıktısı:
Ilk Sayi: 92233720368547
Ikinci Sayi: -92233720368547
Max Sayı: 9223372036854775807
Min Sayı: -9223372036854775808
Ikinci Sayi: -92233720368547
Max Sayı: 9223372036854775807
Min Sayı: -9223372036854775808
Github Adresi : https://github.com/emrakin/CSharpDersleri
Tüm Derslerin Listesi için Tıkla
C# Dersleri 1 - Veri Tipleri : Integer Veri Tipi
Değer ve Referans Tipleri
C# dilinde iki tür veri tipi mevcuttur.Bunlar değer ve referans tipleridir. Değer tipleri; veriyi taşıyan ve taşıdığı veriye göre bellek üzerinde yer dolduran değişken türleridir. Referans türleri ise, bellek bölgesinde veri yerine verinin bellekteki adresini tutarlar ve o adresin gösterdiği yerde de veri tutulur.
Değer tipleri: "int", "long", "float", "double", "decimal", "char", "bool", "byte", "short", "struct", "enum"
Referans tipleri: "string", "object", "class", "interface", "array", "delegate", "pointer"
Integer Veri Tipi:
Integer (int) tam sayıları tuttuğumuz 32 bitlik veri depolayan bir değer tipidir (Value Type). Integer bir veri tipini tanımlamak için int keyword ünden faydalanırız.
Eğer veri tipi integer ve değeri 15 olan bir değişken tanımlamak istersek.
int ilknumara = 15;bura da "int" veri tipini, ilknumara değişkeni, 15 ise değeri ifade eder.
static void Main(string[] args)
{
int ilknumara = 10;
Console.WriteLine(ilknumara);
Console.ReadLine();
}
{
int ilknumara = 10;
Console.WriteLine(ilknumara);
Console.ReadLine();
}
Burada kodu çalıştırdığımızda konsol ekranına "10" yazacaktır.
static void Main(string[] args)
{
int ilknumara = 10;
Console.WriteLine("İlk Sayı: {0}",ilknumara);
Console.ReadLine();
}
{
int ilknumara = 10;
Console.WriteLine("İlk Sayı: {0}",ilknumara);
Console.ReadLine();
}
Kodumuzu bu şekilde yazdığımız da ise konsol ekranında "İlk Sayı: 10" yazacaktır. Burada küme parantezi içine yazdığımız "0" virgülde sonra ki ilk değerdir. Bu olaya index denir ve çoğu programlama dilinde index sıfırdan başlar.
Bu örnekler projenin github reposunda yer almaktadır.
Integer ile ilgili sınırlara gelecek olursak mesela aşağıda ki kodu şu şekilde değiştirsek;
static void Main(string[] args)
{
int ilknumara = 10;
int ikincinumara = -10;
Console.WriteLine("İlk Sayı: {0} - İkinci Sayı: {1}",ilknumara,ikincinumara);
Console.ReadLine();
}
{
int ilknumara = 10;
int ikincinumara = -10;
Console.WriteLine("İlk Sayı: {0} - İkinci Sayı: {1}",ilknumara,ikincinumara);
Console.ReadLine();
}
ve programı çalıştırırsak konsol ekranına 10 ve -10 değerlerini yazacaktır. Demek ki integer veri tipi eksi değerde alabilmektedir.
Bunun yanında bütün veri tiplerinin bir sınırı vardır. Integer veri tipinin sınırı -2147483648 ile 2147483647 arasındadır.
static void Main(string[] args)
{
int ilknumara = 10;
int ikincinumara = -10;
Console.WriteLine("İlk Sayı: {0} - İkinci Sayı: {1}",ilknumara,ikincinumara);
int maxnumara = 2147483647;
int minnumara = -2147483648;
Console.WriteLine("Max Sayı: {0} - Min Sayı: {1}", maxnumara, minnumara);
Console.ReadLine();
}
{
int ilknumara = 10;
int ikincinumara = -10;
Console.WriteLine("İlk Sayı: {0} - İkinci Sayı: {1}",ilknumara,ikincinumara);
int maxnumara = 2147483647;
int minnumara = -2147483648;
Console.WriteLine("Max Sayı: {0} - Min Sayı: {1}", maxnumara, minnumara);
Console.ReadLine();
}
Github Adresi : https://github.com/emrakin/CSharpDersleri
Tüm Derslerin Listesi için Tıkla
14 Haziran 2019 Cuma
Thread ve Multithreading Nedir?
Hepinizin bildiği üzere işletim sistemlerinde uygulamaların çalışmasını sağlayan process(işlem)ler vardır. Bunlar uygulamaları izole ederek çalışan diğer uygulamalarla beraber birbirlerinin verilerini bozmamasını sağlayarak her uygulamalanın kendi memori adreslerinde çalışmasını sağlarlar. Bu uygulamaların CPU ya bakan tarafına geldiğimizde ise bunun için ayrı bir kavram devreye giriyor ve bu kavrama da Thread diyoruz.
Thread ler dillerin kendi yapılarından gelen bir şey değil, işletim sistemlerinin yapısından gelen bir durumdur. İşletim sistemlerinin birden fazla uygulamayı aynı anda çalıştırabilmek için geliştirilmiş bir yaklaşımdır. Thread mantığı olmasaydı aynı anda birden çok uygulama yada program kullanılamaz olur ve diğer uygulama yada program kullanabilmek için mevcut çalışanı sonlandırmamız gerekirdi. Umarım bu kısa giriş Thread kavramını anlayabilmek için yeterli olmuştur.
Not: Anlatım ve örnekleri C# üzerinden gerçekleştiriyorum fakat genel olarak diğer dillerde de mantık hemen hemen aynıdır. Önemli olan meseleyi anlamak
Thread Priority
Bazı durumlarda bir Thread’e öncelik vermek isteyebiliriz. Bu durumda öncelikli işlemyapmasını istediğimiz Thread’e Thread.Priority özelliğini vermeliyiz.
Thread a = new Thread(()=>{
Console.WriteLine("İkinci Thread");
});
Thread b = new Thread(()=>{
Console.WriteLine("Birinci Thread");
});
b.Priority = ThreadPriority.Normal;
a.Start();
b.Start();
Thread.Sleep
Başlatılacak Thread işleminin uygulama çalıştırıldıktan belli bir zaman sonra çalışmasını istiyorsan Thread.Sleep özelliğini kullanabiliriz.
Mesela uygulama çalıştıktan 2sn sonra çalışmasını istediğimiz bir Thread için Thread.Sleep(2000); şeklinde bir komut vermeliyiz.
Thread a = new Thread(()=>{
Thread.Sleep(2000);
Console.WriteLine("İkinci");
});
a.Start();
Thread.Join
Birbirini beklemesi gerek Thread işlemlerinde
Thread.Join kullanılır. Böylece bir önceki iş bitmeden diğer işleme geçiş
yapılması engellenir. Aşağıda ki örnekte a işlemi 2sn sonra başlatılıyor ve bu
işlem bitmeden b işlemine geçilmiyor.
Thread a = new
Thread(()=>{
Thread.Sleep(2000);
Console.WriteLine("ilk
işlem");
});
Thread b = new
Thread(()=>{
Console.WriteLine("Bekletilen
işlem");
});
a.Start();
a.Join();
b.Start();
Şimdilik bu kadar. Thread konusuna devam etmeyi ve
özellikle Thread Locks ve ThreadPools kavramları üzerinde durduğum bir yazı yasmak
istiyorum. Umarım burada ki bilgiler işinize yaramıştır.
22 Mayıs 2019 Çarşamba
C# Erişim Belirleyiciler (Access Modifiers)
PrivateBir nesne private olarak tanımlandığında sadece kendi kod bloğu içerisinden çağrılabilir. Güvenlik nedeniyle dışarıya kesinlikle açmamamız gereken nesnelerde kullanılır.
Public
Bir nesne public olarak tanımlandığında hiç bir kısıtlaması olmaz. Yani hem kendi kod bloğu üzerinden hem de dışarıdan hatta farklı projeler üzerinden dahi çağrılabilir.
Internal
Kendi projesi içerisinde public, farklı bir projeden/dışarıdan çağırılmak istenildiğinde ise private özelliklerini taşır. Yani aynı Assembly (dll) üzerinde istediğiniz şekilde kullanabilirsiniz ancak dışarıdan (farklı bir projeden) çağramayız.
Protected
Bir nesne protected olarak tanımlandığında yalnızca bulunduğu class üzerinde ve bu class ı miras alan (bu class’tan türetilmiş) classlar üzerinden çağrılabilir.
Proteced Internal
Bir nesne protected internal olarak tanımlandığında aynı protected gibi kendi bulunduğu class üzerinde ve bu class ı miras alan classlar üzerinden çağrılabilir. Artı olarak aynı proje (assembly/dll) üzerinde olmasalar dahi, tanımlandığı class’tan türetilmiş diğer class’ların içinden de çağrılabilirler.
Özel bir durum olmadıkça varsayılan olarak değişkenler ve methodlar private, classlar ise internal dır.
30 Nisan 2019 Salı
.Net Core Uygulamasında Redis Cache Kullanımı
Bu yazıda Docker üzerinde bir Redis Container'ı koşturup, artından bir .Net Core Mvc projesinde nasıl kullanılacağını inceleyeceğiz. Redis (distributed cahce)' de amaç, bir web sayfası yada bir web API' dan gelen istekler olduğunda her seferinde servise ya da DB'ye gitmektense bu istekleri In Memory olarak yani ram'den karşılanması ve bu sayede performansın arttırılmasıdır.
Yazının tamamında kullanılacak teknolojiler;
- Docker
- Redis
- .Net Core
Öncelikle eğer makinamızda Docker yok ise https://www.emrakin.com/2019/04/docker-nedir-neden-kullanlr-nasl.html bu adresten Docker kurulumu hakkında bilgi edinebilirsiniz.
Docker üzerinde bir Redis Container koştumak için aşağıdaki kodu kullanalar "6379" portundan ayağa kalkması sağlanır.
docker run -d --name Redis -p 6379:6379 redis
Ben .Net Core Mvc projesinde Redis için ServiceStack kullandım. İlgili kütüphaneyi https://www.nuget.org/packages/ServiceStack.Redis.Core bu linkten inceleyebilir ve Nuget ile projenize ekleyebilirsiniz.
PM> Install-Package ServiceStack.Redis.Core
Redis'in .Net Core projesinde kullanımı için Startup.cs'de AddDistributedRedisCache() methodu ile redisserver'ın IP ve Portu'nu tanımlıyoruz.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDistributedRedisCache(options =>
{
options.InstanceName = "RedisNetCoreSample";
options.Configuration = "localhost:6379"; //Your Redis Connection
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDistributedRedisCache(options =>
{
options.InstanceName = "RedisNetCoreSample";
options.Configuration = "localhost:6379"; //Your Redis Connection
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
AddDistributedRedisCache() methodunu Startup.cs' de kullanmak için Microsoft.Extensions.Caching.Redis'i Nugetten projenize dahil etmeniz gerekiyor.
PM> Install-Package Microsoft.Extensions.Caching.Redis
Models: Models klasörü altında Person.cs adında bir sınıf oluşturuyoruz.
public class Personal
{
public int ID { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public int Age { get; set; }
}
Projemize RedisRepository adında bir klasör ekliyoruz. Bu klasör altında Redis'le ilgili işlemlerimizi bir interface yapı da tutacağız. RedisRepository klasörünün altında IRedisService adında bir interface oluşturuyoruz.{
public int ID { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public int Age { get; set; }
}
public interface IRedisService
{
List<Person> GetAll(string cachekey);
Person GetById(string cachekey);
}
{
List<Person> GetAll(string cachekey);
Person GetById(string cachekey);
}
RedisRepository klasörü altına IRedisService.cs den inheritance olmuş RedisManager.cs adında bir sınıf oluşturuyoruz.
public class RedisManager : IRedisService
{
public List<Person> GetAll(string cachekey)
{
using (IRedisClient client = new RedisClient())
{
List<Person> dataList = new List<Person>();
List<string> allKeys = client.SearchKeys(cachekey);
foreach (string key in allKeys)
{
dataList.Add(client.Get<Person>(key));
}
return dataList;
}
}
public Person GetById(int personId, string cachekey)
{
using (IRedisClient client = new RedisClient())
{
var redisdata = client.Get<Person>(cachekey);
return redisdata;
}
}
}
{
public List<Person> GetAll(string cachekey)
{
using (IRedisClient client = new RedisClient())
{
List<Person> dataList = new List<Person>();
List<string> allKeys = client.SearchKeys(cachekey);
foreach (string key in allKeys)
{
dataList.Add(client.Get<Person>(key));
}
return dataList;
}
}
public Person GetById(int personId, string cachekey)
{
using (IRedisClient client = new RedisClient())
{
var redisdata = client.Get<Person>(cachekey);
return redisdata;
}
}
}
IRedisServise ve RedisManager'ı Startup.cs'e dahil etmemiz gerekiyor.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDistributedRedisCache(options =>
{
options.InstanceName = "RedisNetCoreSample";
options.Configuration = "localhost:6379"; //Your Redis Connection
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddScoped<IRedisService, RedisManager>();
}
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDistributedRedisCache(options =>
{
options.InstanceName = "RedisNetCoreSample";
options.Configuration = "localhost:6379"; //Your Redis Connection
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddScoped<IRedisService, RedisManager>();
}
HomeController.cs/HomeController(): Öncelikle person sınıfı tipinde yeni bir kayıt oluşturup Redis cache'e atıyoruz.
- "cachedata.SetValue("Person"+personvalue.ID, personvalue);": Redis'de "Person+ID" key'ine karşılık value değeri olarak oluşturulan dataByte[] dizisi SetValue() methodu ile atıyoruz.
private readonly IRedisService _redisService;
public HomeController(IRedisService redisService)
{
_redisService = redisService;
using (IRedisClient client = new RedisClient())
{
if (client.SearchKeys("Person*").Count == 0)
{
var personvalue = new Person();
personvalue.ID = 1;
personvalue.Name = "Emrah";
personvalue.Surname = "Akın";
personvalue.Age = 40;
var cachedata = client.As<Person>();
cachedata.SetValue("Person"+personvalue.ID, personvalue);
}
}
}
public HomeController(IRedisService redisService)
{
_redisService = redisService;
using (IRedisClient client = new RedisClient())
{
if (client.SearchKeys("Person*").Count == 0)
{
var personvalue = new Person();
personvalue.ID = 1;
personvalue.Name = "Emrah";
personvalue.Surname = "Akın";
personvalue.Age = 40;
var cachedata = client.As<Person>();
cachedata.SetValue("Person"+personvalue.ID, personvalue);
}
}
}
HomController.cs/Index: Redis'e "Person" key'i ile atılan tüm verileri getirmek için "Person*" ile çağırıyoruz.
public IActionResult Index()
{
const string cacheKey = "Person*";
var redisdata = _redisService.GetAll(cacheKey);
return View(redisdata);
}
{
const string cacheKey = "Person*";
var redisdata = _redisService.GetAll(cacheKey);
return View(redisdata);
}
Index.cshtml: View modelden gelenleri ekrana yansıtıyoruz
@model IEnumerable<NetCoreRedis.Models.Person>
@{
ViewData["Title"] = "Index";
}
<table class="table">
<thead>
<tr>
<th>
ID
</th>
<th>
Name
</th>
<th>
SurName
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.ID)
</td>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Surname)
</td>
<td>
@Html.ActionLink("Details", "Home", new { id = item.ID }) |
</td>
</tr>
}
</tbody>
</table>
HomeController.cs/Detail: @{
ViewData["Title"] = "Index";
}
<table class="table">
<thead>
<tr>
<th>
ID
</th>
<th>
Name
</th>
<th>
SurName
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.ID)
</td>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Surname)
</td>
<td>
@Html.ActionLink("Details", "Home", new { id = item.ID }) |
</td>
</tr>
}
</tbody>
</table>
public IActionResult Detail(int Id)
{
string cacheKey = "Person"+Id;
var redisdata = _redisService.GetById(cacheKey);
return View(redisdata);
}
{
string cacheKey = "Person"+Id;
var redisdata = _redisService.GetById(cacheKey);
return View(redisdata);
}
Detail.cshtml:
@model NetCoreRedis.Models.Person
@{
ViewData["Title"] = "Detail";
}
<h3><b>Person:</b></h3>
<table class="table">
<tr>
<td>Ad:</td>
<td>@Model.Name</td>
</tr>
<tr>
<td>Soyad:</td>
<td>@Model.Surname</td>
</tr>
<tr>
<td>Yaş:</td>
<td>@Model.Age</td>
</tr>
</table>
@{
ViewData["Title"] = "Detail";
}
<h3><b>Person:</b></h3>
<table class="table">
<tr>
<td>Ad:</td>
<td>@Model.Name</td>
</tr>
<tr>
<td>Soyad:</td>
<td>@Model.Surname</td>
</tr>
<tr>
<td>Yaş:</td>
<td>@Model.Age</td>
</tr>
</table>
Docker container olarak ayaklandırdığımız Redis cache üzerinden key value'larımızı görmek için terminal ekranına aşağıdaki kodu yazdıktan sonra "Keys *" komunu kullanabilirsiniz.
docker exec -it Redis redis-cli
Projenin bitmiş haline https://github.com/emrakin/.NetCore-Redis buradan ulaşabilirsiniz.
İlgili Kaynaklar:






























