.NET Projeleri Nasıl Önyüklenir ve Oluşturulur
Yayınlanan: 2022-03-11.NET projesi oluştur
Sıfırdan bir .NET projesi oluşturmak, Visual Studio sihirbazını kullanmak kadar basittir. File => New Project
seçeneğine veya mevcut bir çözüme Add New Project
seçeneğine gidin. Yeni bir proje oluşturulduktan sonra hemen kodlamaya başlayabilirsiniz. Ancak, sihirbazlar tarafından oluşturulan varsayılan proje ayarları, kalite konusunda çok düşük bir çıta oluşturdukları için profesyonel ekipler için pek kabul edilemez. Ayrıca, hiçbir sihirbaz, kendi geliştirme ortamınızda gerçekleştirmeniz gereken diğer kurulum adımlarını bilemez.
Bu makalede, gelecekteki bir teknik borcu en aza indirmek için önemli olan yeni bir proje oluşturur oluşturmaz etkinleştirmeniz gereken birkaç önemli ayarda size yol göstereceğim. Ayrıca, birçok .NET geliştiricisinin çözümleri ve yeni projeleri yapılandırırken uyguladığı bazı yaygın uygulamaları gözden geçireceğiz. Bu fikirlerden bazılarını uygulamıyor olsanız bile, öğrenmek ve çoğu takımın ne yaptığına dair bir fikir edinmek güzeldir.
Yapı
İyi tanımlanmış bir yapıya sahip olmak karmaşık projeler için hayati önem taşır. Bu, yeni gelenler bir ekibe katıldığında işe başlama deneyimini geliştirir ve eski projeleri desteklerken hayatınızı kolaylaştırır. İyi bir yapının iki temel göstergesi vardır:
- Çözüm ve proje klasörlerini kullanma
- tutarlı adlandırma
klasörler
Bazen sanal klasörler olarak da adlandırılan çözüm klasörleri, projelerinizi gruplamak için çok kullanışlı bir araçtır. Çözüm Gezgini görünümünde, sağ tıklayın ve Add => New Solution Folder
öğesini seçin, ardından mevcut projelerden herhangi birini bu yeni klasöre sürükleyip bırakın. Bu klasörler dosya sisteminde yansıtılmaz, fiziksel yapıyı değiştirmeden tutmanıza izin verir, bu nedenle projeleri bir Çözüm Klasöründen diğerine taşımak onları fiziksel olarak taşımaz.
Numaralandırılmış öneklere sahip olmak gerekli değildir, ancak klasörlerin Solution Explorer penceresinde sıralı görünmesini sağlar.
Visual Studio, Bölümlenmiş tek çözüm veya Çoklu çözüm modellerinden yararlanarak aynı anda birden çok çözümle çalışabilir. Nadiren kullanılırlar, bu yüzden onları bu makalede ele almayacağım.
Çözüm klasörlerinden farklı olarak, Proje klasörleri fiziksel klasör yapısıyla eşleşir ve bu nedenle diskte gerçek klasörler olarak kalır. Ayrıca, bir C# kodu içeren Proje klasörleri, projenin ad alanıyla eşleşmelidir. Bu, navigasyonu oldukça doğal hale getirir. Hatta bu tür uyumsuzluklarda uyarmak için bir ReSharper kuralını etkinleştirebilirsiniz.
adlandırma
Adlandırmayla ilgili olarak uygulanması önerilen birkaç kural vardır:
- CamelCase'i kullanın.
- Bir proje adı, çıktı derleme adıyla eşleşmelidir.
- Otomatik testler içeren bir proje
.Tests
son ekine sahip olmalıdır. - Tüm proje adlarının
Company.Product
gibi ortak bir öneki olmalıdır.
Birkaç makul kural da vardır. Bunları ne zaman uygulayacağınıza sağduyuya (ve elbette İngilizce dilbilgisine) dayanarak kendiniz karar vermelisiniz:
- Bir kap (proje veya klasör) aynı türden birden çok örnek içerdiğinde (örneğin
Tests
veyaSystem.Collections
) konuları çoğul biçimde kullanın. - Tüm kap tek bir varlık hakkında kod içerdiğinde tekil form kullanın (örn. System.Collections.ObjectModel`).
- Kısa kısaltmalar için
System.IO
yaptığı gibi büyük harf kullanın. - Uzun kısaltmalar için
Modules.Forex.
.
Temel kural: Kısa bir kısaltma üç karakterden uzun olmamalıdır.
Çözüm Yapılandırma
Bir çözümü yapılandırmak, ortamınız için ihtiyaç duyduğunuz tüm altyapı dosyalarını sağlamak kadar basittir. Bazıları daha sonra eklenebilse de (CI entegrasyon dosyaları gibi), en başında birkaç dosyaya sahip olmanız daha iyi olur.
Yeniden Keskinleştirici Ayarları
Profesyonel .NET geliştiricisiyseniz, büyük olasılıkla ReSharper kullanıyorsunuzdur. ReSharper, ayarlarını yönetmede çok esnektir. Ekip lideri olarak, diğer geliştiriciler tarafından kullanılacak Team Shared ayarlarını oluşturabilir ve dağıtabilirsiniz. Team Shared ayarları, .DotSettings
uzantılı bir dosyada saklanır. Dosya adı Visual Studio çözüm adıyla eşleşiyorsa ReSharper bu ayarları otomatik olarak seçer:
MyCompany.MyProduct.sln MyCompany.MyProduct.sln.DotSettings
Bu nedenle, nihayetinde tüm takıma bazı ayarları uygulamak istiyorsanız, bu dosyayı en baştan oluşturmalısınız. var
anahtar sözcüğünü kullanma (veya kullanmama) kuralı buna iyi bir örnek olabilir. Ekip Paylaşılan ayarlar dosyanız yalnızca bu kurala sahip olabilir, diğerleri ise geliştiricilerin tercihidir. Aynı şekilde ReSharper ayarlarının proje bazında ayarlanabileceğini belirtmekte fayda var, çünkü değiştiremeyeceğiniz bazı eski kodunuz olabilir (örneğin, var
anahtar sözcüğünü kullanmak için değiştirin).
Bu dosyayı örnekte gösterildiği gibi doğru adlandırdıysanız, yeni bir ReSharper kurulumuna sahip herhangi bir yeni Visual Studio örneği bu dosyayı otomatik olarak seçecek ve kuralları uygulayacaktır. Bu dosyayı kaynak denetimine vermeyi unutmayın.
Stil Polis Kuralları
ReSharper ayarlarıyla aynı şekilde StyleCop ayarlarını paylaşabilirsiniz. ReSharper kullanıyorsanız, muhtemelen ReSharper'dan StyleCop'tan yararlanacak bir entegrasyon eklentisi yüklemişsinizdir. Ancak StyleCop, ayarlarını bağımsız olarak Settings.StyleCop
adlı dosyalarda saklar. Aynı şekilde bu dosyaya çözüm dosyası ve proje dosyaları ile birlikte sahip olabilirsiniz.
StyleCop kullanıyorsanız, StyleCop yapılandırma aracını çalıştırmayı ve yapmak istemediğiniz kontrolleri devre dışı bırakmayı unutmayın. Varsayılan olarak, tüm kontroller etkindir. Yeni ayarları bu dosyaya kaydedin ve kaynak kontrolünü taahhüt edin.
Metin Dosyaları
Herkese açık bir ürün oluşturuyorsanız ve kaynak kodunu yayınlayacaksanız, bu dosyaları da oluşturmayı ve kaydetmeyi unutmayın:
README.md LICENSE
README.md dosyası için README.md
formatını kullanmanızı öneririm çünkü bu dosya endüstriyel bir standart haline geldi ve GitHub gibi genel kaynak kontrol servislerinin yanı sıra BitBucket (eski Stash) gibi şirket içi sunucular tarafından desteklendi.
NuGet Spesifikasyonları
NuGet Gallery'de dağıtılacak bir kitaplık oluşturuyorsanız, büyük olasılıkla MyProject.nuspec
gibi paket belirtim dosyaları oluşturmanız gerekir. Bu dosyaları manuel olarak oluşturmayı ve kaynak denetimine vermeyi tercih ediyorum. Paketler genellikle Sürekli Entegrasyon (kısaca CI) işinizden biri tarafından yayınlanır, ancak istediğiniz zaman konsoldan aşağıdaki gibi manuel olarak bir paket oluşturabilir ve yayınlayabilirsiniz:
nuget.exe pack MyLibrary.nuspec
Bu komutu çalıştırmadan önce paket sürümünü artırmayı unutmayın.
CI'ye özel dosyalar
Hepimiz farklı CI sunucuları kullanıyoruz ve hepsinin farklı yapılandırma komut dosyaları ve ayarları var. Eklemeyi düşünebileceğiniz bazı yaygın eklemelerden bahsedeceğim:
- Belirli işler için CI sunucusunda yürütülecek testleri içeren derlemeleri belirten NUnit ayarları. Tüm testler pratik olarak birkaç kategoriye ayrılmıştır. Her derlemede çalıştırılması gereken birim testleri , her gece yürütülen performans testleri ve sürüm bazında yürütülen entegrasyon testleri vardır.
- Test kapsamı için hangi test derlemelerinin analiz edilmesi gerektiğini belirten NCover ayarları.
- Yazılım metriklerini belirleyen SonarQube ayarları toplanacaktır.
- NAnt, PowerShell veya yalnızca Windows toplu iş dosyaları gibi iş komut dosyaları.
Projeleri Yapılandırma
Proje dosyaları, yani .csproj
veya .vbpro
, Visual Studio ve MSBuild tarafından kullanılan tüm ayarları içerir. Ancak, hepsi Proje Özellikleri penceresinden kullanılamaz. Bu dosyaları Visual Studio'da manuel olarak düzenlemek için aşağıdakileri yapmalısınız:
- Solution Explorer görünümünde bir projeye sağ tıklayın.
- Projeyi Kaldır'ı seçin.
- xyz.csproj düzenle eylemini seçmek için tekrar sağ tıklayın.
- Düzenlemeyi tamamlayın.
- Projeye tekrar sağ tıklayın ve Projeyi Yeniden Yükle öğesini seçin.
Alternatif olarak, bir proje dosyasını favori metin düzenleyicinizde açabilir, düzenleyebilir ve kaydedebilirsiniz. Visual Studio penceresine geri döndüğünüzde, değiştirilen projeyi yeniden yüklemeniz istenecektir.
Uyarılar Kontrolü
Yüksek kaliteli bir yazılım oluşturmak, derleme uyarılarını asla göz ardı etmemenizi gerektirir. Bu nedenle, maksimum uyarı seviyesini etkinleştirmeli ve herhangi bir uyarıyı hata olarak değerlendirmelisiniz. Bunu Debug ve Release gibi sahip olduğunuz tüm yapı yapılandırmaları için yapmanız gerektiğini unutmayın. Bunu yapmanın en iyi yolu, ortak özellik grubuna aşağıdaki ayarları yazmaktır:
<WarningLevel>4</WarningLevel> <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
Diğer mülk gruplarında aynı ayarlara sahip olmadığınızdan emin olun. Aksi takdirde, ortak gruptan karşılık gelen özellikleri geçersiz kılarlar.
FxCop
FxCop'u çalıştırmak, her derlemede yapmak için yalnızca pratiktir. Çoğu takım ciddi hatalar olmadığından emin olmak için zaman zaman (genellikle bir sürümden önce) FxCop'u çalıştırmayı tercih eder. Ancak, her derlemede nihai kontrol yapmak istiyorsanız, bu seçeneği ekleyin:
<RunCodeAnalysis>true</RunCodeAnalysis>
StyleCop gibi FxCop'un da kök klasöre yerleştirilebilen ve kaynak kontrolüne eklenebilen kendi ayarlarına sahip olduğunu unutmayın. Bu ayarlar büyük olasılıkla FxCop'u CI sunucularında çalıştırırken kullanılır.
belgeler
Bu kısım XmlDoc ile ilgilidir. Genel bir API oluşturuyorsanız, API belgeleri oluşturmalı ve sürdürmelisiniz. Çoğu geliştirici, API geliştirme (gerçek kodlama) ile başlar ve bir sürümden hemen önce proje ayarını etkinleştirir Build / XML documentation file
. Doğal olarak, başka bir yeniden oluşturma işleminden sonra bir sürü hata ortaya çıkıyor, çünkü her eksik XmlDoc bir derleme hatasıyla sonuçlanıyor. Bunu önlemek için, en başta belirtilen seçeneği etkinleştirmelisiniz.
Düzgün bir belge yazamayacak kadar tembelseniz veya çok fazla metin yazmayı sevmiyorsanız, GhostDoc gibi bu işlemi otomatikleştiren araçları deneyin.
Kod Sözleşmeleri
Code Contracts, çalışma zamanı denetimi, statik analiz ve belgeler için kodunuzdaki ön koşulları, son koşulları ve nesne değişmezlerini ifade etmenize olanak tanıyan, Microsoft Research'ün mükemmel bir çerçevesidir. Bunu birçok kritik projede kullandım ve çok yardımcı oldu, bu yüzden denemenizi tavsiye ederim.
Kod Sözleşmelerini kullanmaya karar verirseniz, yeni bir proje oluşturduğunuzda, en başta Sözleşmeleri etkinleştirmeniz önemlidir. Geliştirmenin ortasında Sözleşmeler eklemek mümkündür, ancak Kişilerin birbiriyle eşleşmesi için birçok sınıfta değişiklik yapılması gerekir. Bu nedenle, gerekli tüm ayarları etkinleştirmeyi unutmayın (en azından CodeContractsEnableRuntimeChecking
) ve bu ayarların ortak özellik grubunda göründüğünden emin olun.

Stil Polis İcrası
Daha önce geliştirme süresi için StyleCop yapılandırmasından bahsetmiştik. Ancak, projeniz bir CI sunucusunda oluşturulduğunda, ReSharper'ın orada hiçbir etkisi yoktur ve bu nedenle StyleCop doğrulamasının MSBuild ile çalışmasını sağlamalıyız.
Bu genellikle proje dosyasının manuel olarak değiştirilmesiyle yapılır. Projeyi Visual Studio'da kaldırmanız, proje dosyasını düzenlemeniz ve ardından projeyi geri yüklemeniz gerekir:
<PropertyGroup> <!— add this to the common property group (common to Debug/Release/etc) —> <StyleCopTreatErrorsAsWarnings>false</StyleCopTreatErrorsAsWarnings> </PropertyGroup> <!— add this Import in the very bottom —> <Import Project="$(ProgramFiles)\MSBuild\Microsoft\StyleCop\v4.3\Microsoft.StyleCop.targets">
StyleCopTreatErrorsAsWarnings
ayarı, söylediklerini yapacak: herhangi bir StyleCop kuralı ihlali durumunda yapınızı bozacaktır. MSBuild'in yapı zincirine StyleCop görevi eklemesi için içe aktarma öğesi gereklidir.
Program Files
yolunu fark etmiş olabilirsiniz. Geliştiricilerin farklı StyleCop sürümleri kurulu olabileceğinden, bazı ekipler aynı StyleCop kurulumunun özel bir kopyasını kaynak kontrolü altında tutmayı tercih eder. Bu durumda, yol göreceli olacaktır. StyleCop'u yerel olarak kurmanız gerekmediğinden, bu aynı zamanda CI makinelerinin kurulumunu da kolaylaştırır.
Montaj Bilgileri
Visual Studio sihirbazı tarafından oluşturulan her .NET projesinde, bazı Assembly
özniteliklerini içeren AssemblyInfo.cs
dosyası otomatik olarak doldurulur ( Özellikler alt klasörüne bakın), ancak hiçbir sihirbaz sizin için tüm Assembly
özniteliklerini dolduramaz. En azından şu özelliklerin doldurulduğundan emin olun:
-
AssemblyTitle
-
AssemblyDescription
-
AssemblyCompany
-
AssemblyProduct
-
AssemblyCopyright
-
AssemblyVersion
Bu minimum minimum, dağıtacağınız tüm montajlar için gereklidir. Bunun pratik bir nedeni NuGet'tir: Seçili derleme dosyasından otomatik NuGet belirtimi oluşturma kullanıyorsanız, bu araç bu özelliklerden gerekli bilgileri türetecektir.
Ayrıca en başta bir mülkü daha doldurabilirsiniz:
InternalsVisibleTo
Bu özellik, dahili sınıfları ve arabirimleri belirtilen derlemeye görünür kılar. Bu genellikle projeniz için oluşturacağınız otomatik testler için kullanılır.
Bağlantı Dizileri
Bağlantı dizelerinin nasıl yönetileceği, Stack Overflow'ta çok popüler bir sorudur. Sorun, her geliştirici veya bir CI işi için bağlantı dizelerinin nasıl benzersiz hale getirileceği ve kaynak kodu yayınlanırken bağlantı ayrıntılarının gösterilmemesidir.
App.config
(masaüstü uygulamaları için) veya Web.config
(web uygulamaları için), çalışma zamanında user.config
dosyasını yükleyecek olan aşağıdaki ayarı yapın. Bunu kaynak kontrolünüz altında tutun:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings configSource="user.config"></connectionStrings> </configuration>
Görünüşe göre, user.config
dosyası kaynak kontrolünden dışlanmalıdır ve her geliştirici, bağlantı dizesi gizliliğini koruyarak bu dosyanın yerel bir kopyasına sahip olmalıdır:
<connectionStrings> <add name="test" connectionString="Server=.;Database=...;"/> </connectionStrings>
.gitignore
Git'i kaynak denetimi olarak kullananlar için .gitignore
dosyasına bazı dosya kalıpları eklemek önemlidir. Ancak, akıllı topluluğumuz zaten burada bulunabilecek genelleştirilmiş bir dosya oluşturmuştur: github.com/github/gitignore/blob/master/VisualStudio.gitignore.
Bunu bir referans .gitignore
dosyası olarak almalı ve ek olarak ihtiyaç duyabileceğiniz özel hariç tutmalarınızı eklemelisiniz.
GitHub Rozetleri
README
projesinin sayfasında görünen güzel görünümlü rozetler görmüş olabilirsiniz. Projenizi GitHub'da yayınlıyorsanız, projenizi aşağıdakiler için kamu hizmetlerine bağlamayı düşünün:
- Bina: Bir yapının başarısız olduğunu veya geçtiğini göstermek için.
- Test Etme: test kapsamını ve test yürütme durumunu göstermek için.
- Yayımlama: en son NuGet paketi sürümünü göstermek için.
Rozetlerin ve ilgili hizmetlerin tam listesi shields.io'da bulunabilir. Açık Kaynak projeleri için iyi olan birçok ilginç rozet bulabilirsiniz.
Projenizi seçilen bir hizmete kaydettirdiğinizde, size resmin bir bağlantısı ve README.md
dosyanıza ekleyebileceğiniz eksiksiz bir markdown-syntax bağlantısı verilecektir. Bu arada, Readme dosyaları için markdown'ı tercih etmenizin nedenlerinden biri de budur.
Roslyn projesinden örnek indirim rozetleri:
[](http://dotnet-ci.cloudapp.net/job/roslyn_master_win_dbg_unit32/)](http://dotnet-ci.cloudapp.net/job/roslyn_master_win_dbg_unit32/badge/icon)](http://dotnet-ci.cloudapp.net/job/roslyn_master_win_dbg_unit32/)) [](https://gitter.im/dotnet/roslyn?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)](https://gitter.im/dotnet/roslyn](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/dotnet/roslyn?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge))
Otomatik Çözüm Yapısı Doğrulaması
Bu makalede tartıştığımız tüm ayarları yapmış olsanız bile, geliştiricilerinizden biri er ya da geç bunları değiştirebilir ve değişiklikleri kaynak denetimine aktarabilir. Bazen bu yanlışlıkla olur ve genellikle bu değişiklikler kod incelemesi sırasında yakalanmaz. Bu kazaların dışında, aşağıdaki yaygın hatalara dikkat etmeliyiz:
- Kötü referanslar : Birisi, diğerlerinin sahip olmadığı yerel bir derlemeye atıfta bulunduğunda veya birisi diskten bir dosyayı sildiğinde, o dosyaya olan bağlantı
.csproj
dosyasında kalırken. Bu kesinlikle yapıyı bozacaktır, ancak değişiklik yapıldığında ve diğerleri onu çektiğinde çok geç olabilir. Bu, özellikle derleme sırasında doğrulayamayacağınız statik web dosyaları için çok önemlidir. - Adlandırma tutarlılığı : StyleCop gibi araçlar C# kaynak kodunu kontrol edebilir, ancak hiçbir araç Proje dosyaları veya Derleme özellikleri için kuralları uygulayamaz. İyi bir örnek şudur: Projeleri çıktı derleme adıyla eşleşecek şekilde adlandırmak istiyoruz ve proje adlarının
MyCompany.MyProduct
gibi ortak bir önek olmasını istiyoruz.
Kod İncelemelerinde bu hataları izlemenin hataya açık olduğunu ve otomatikleştirilmesi gerektiğini buldum. Bu yüzden, çözüm tutarlılığını doğrulamak için bunları ve diğer birçok kontrolü gerçekleştiren basit bir araç yazdım. SolutionInspector ile tanışın. Bu Açık Kaynaktır ve MIT lisansı altında dağıtılır. Kaynak koddan oluşturabilir veya NuGet'ten yükleyebilirsiniz:
Install-Package SolutionInspector
Araç, tüm çözüm yapısını inceler ve birçok doğrulama kuralı uygular. Kurallar, diğer çözüm dosyalarıyla birlikte yerleştirilen XML dosyaları tarafından yapılandırılır. Ayarları proje bazında kontrol etmek için, aynı dosyayı farklı ayarlarla ilgili proje klasörüne eklemeniz yeterlidir.
Varsayılan olarak yapılandırma dosyası gerekmez. Bu durumda araç, mevcut tüm kuralları uygular ve tüm sorunları konsola verir.
İşte yapılandırma dosyası örneği:
<?xml version="1.0" encoding="utf-8"?> <Settings xmlns:xsi="[http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">](http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">) <SolutionSettings> <MinSolutionFormatVersion>12.00</MinSolutionFormatVersion> <MaxSolutionFormatVersion>12.00</MaxSolutionFormatVersion> <DetectMissingFiles>true</DetectMissingFiles> <ProjectNamePrefix>MyCompany.MyProduct.</ProjectNamePrefix> <ProjectNameIsFileName>true</ProjectNameIsFileName> <IgnoredProjects> AVerySpecialProject1; AVerySpecialProject2; </IgnoredProjects> </SolutionSettings> <ProjectSettings> <DetectMissingFiles>true</DetectMissingFiles> <AllowBuildEvents>true</AllowBuildEvents> <AssemblyNameIsProjectName>true</AssemblyNameIsProjectName> <RootNamespaceIsAssemblyName>true</RootNamespaceIsAssemblyName> <RequiredImports>StyleCop.MSBuild.Targets</RequiredImports> <Properties> <TreatWarningsAsErrors>true</TreatWarningsAsErrors> <StyleCopTreatErrorsAsWarnings>false</StyleCopTreatErrorsAsWarnings> </Properties> </ProjectSettings> </Settings>
Ayarlar oldukça açıklayıcı olsa da, bazılarını açıklayacağım:
-
MinSolutionFormatVersion
/MaxSolutionFormatVersion
, geliştiricilerinizin Visual Studio sürümünü değiştirmesini engeller. -
DetectMissingFiles
, statik web içeriği veya çözüme veya projeye eklenen diğer kod dışı dosyalar için çok kullanışlıdır. -
AllowBuildEvents
, gereksiz şeyler yapabilecek özel derleme olaylarının eklenmesini engelleyebilir. -
Properties
en esnek öğedir: Bilinen özellikler veya özel özellikler olsun, herhangi bir özelliği istediğiniz değerlerle karşılaştırabilirsiniz.
Çözüm
Yeni bir projeye başlarken uygulayabileceğiniz çeşitli standart uygulamaları, yapılandırma dosyalarını ve proje ayarlarını inceledik. Bunu en baştan yapmak, gelecekteki teknik borcu azaltacak ve ürün kaynak kodunuzun güzel ve profesyonel görünmesini sağlayacaktır. Açık Kaynak projeleri için bu özellikle önemlidir, çünkü herhangi bir katkıda bulunan kişi, çözüm yapılandırmalarını ve proje dosyalarını inceleyerek beklentilerinizi bilir.