diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json
index 5af6a13c50..b7f7cb41a5 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json
@@ -1,5 +1,161 @@
{
"culture": "tr",
"texts": {
+ "Permission:Organizations": "Organizasyonlar",
+ "Permission:Manage": "Organizasyonları Yönet",
+ "Permission:DiscountRequests": "İndirim Talepleri",
+ "Permission:DiscountManage": "İndirim Taleplerini Yönet",
+ "Permission:Disable": "Devre Dışı Bırak",
+ "Permission:Enable": "Etkinleşir",
+ "Permission:EnableSendEmail": "E-Posta Göndermeyi Etkinleştir",
+ "Permission:SendEmail": "E-Posta Gönder",
+ "Permission:NpmPackages": "NPM Paketleri",
+ "Permission:NugetPackages": "Nuget Paketleri",
+ "Permission:Maintenance": "Bakım",
+ "Permission:Maintain": "Bakım Yap",
+ "Permission:ClearCaches": "Önbelleği temizle",
+ "Permission:Modules": "Modüller",
+ "Permission:Packages": "Paketler",
+ "Permission:Edit": "Güncelle",
+ "Permission:Delete": "Sil",
+ "Permission:Create": "Oluştur",
+ "Permission:Accounting": "Muhasebe",
+ "Permission:Accounting:Quotation": "Fiyatlandırma",
+ "Permission:Accounting:Invoice": "Fatura",
+ "Menu:Organizations": "Organizasyonlar",
+ "Menu:Accounting": "Muhasebe",
+ "Menu:Packages": "Paketler",
+ "Menu:DiscountRequests": "İndirim Talepleri",
+ "NpmPackageDeletionWarningMessage": "Bu NPM Paketi silinecektir. Onaylıyor musunuz?",
+ "NugetPackageDeletionWarningMessage": "Bu Nuget Paketi silinecektir. Onaylıyor musunuz?",
+ "ModuleDeletionWarningMessage": "Bu Modül silinecektir. Onaylıyor musunuz?",
+ "Name": "İsim",
+ "DisplayName": "Görüntülenen isim",
+ "ShortDescription": "Kısa açıklama",
+ "NameFilter": "İsim",
+ "CreationTime": "Oluşturma zamanı",
+ "IsPro": "Is pro",
+ "ShowOnModuleList": "Modül listesinde göster",
+ "EfCoreConfigureMethodName": "Metot adını yapılandır",
+ "IsProFilter": "Is pro",
+ "ApplicationType": "Uygulama tipi",
+ "Target": "Hedef",
+ "TargetFilter": "Hedef",
+ "ModuleClass": "Modül sınıfı",
+ "NugetPackageTarget.DomainShared": "Domain Shared",
+ "NugetPackageTarget.Domain": "Domain",
+ "NugetPackageTarget.Application": "Application",
+ "NugetPackageTarget.ApplicationContracts": "Application Contracts",
+ "NugetPackageTarget.HttpApi": "Http Api",
+ "NugetPackageTarget.HttpApiClient": "Http Api Client",
+ "NugetPackageTarget.Web": "Web",
+ "NugetPackageTarget.EntityFrameworkCore": "DeleteAllEntityFramework Core",
+ "NugetPackageTarget.MongoDB": "MongoDB",
+ "Edit": "Güncelle",
+ "Delete": "Sil",
+ "Refresh": "Yenile",
+ "NpmPackages": "NPM Paketleri",
+ "NugetPackages": "Nuget Paketleri",
+ "NpmPackageCount": "NPM Paket Sayısı",
+ "NugetPackageCount": "Nuget Paket Sayısı",
+ "Module": "Modüller",
+ "ModuleInfo": "Modül bilgisi",
+ "CreateANpmPackage": "Bir NPM paketi oluştur",
+ "CreateAModule": "Bir modül oluştur",
+ "CreateANugetPackage": "Bir Nuget paketi oluştur",
+ "AddNew": "Yenisini Ekle",
+ "PackageAlreadyExist{0}": "\"{0}\"isimli paket zaten eklendi.",
+ "ModuleAlreadyExist{0}": "\"{0}\" isimli modül zaten eklendi.",
+ "ClearCache": "Önbelleği Temizle",
+ "SuccessfullyCleared": "Başarıyla temizlendi",
+ "Menu:NpmPackages": "NPM Paketleri",
+ "Menu:Modules": "Modüller",
+ "Menu:Maintenance": "Bakım",
+ "Menu:NugetPackages": "Nuget Paketleri",
+ "CreateAnOrganization": "Bir organizasyon oluştur",
+ "Organizations": "Organizasyonlar",
+ "LongName": "Uzun isim",
+ "LicenseType": "Lisans tipi",
+ "MissingLicenseTypeField": "Lisans tipi alanı zorunludur.",
+ "LicenseStartTime": "Lisans başlama zamanı",
+ "LicenseEndTime": "Lisans bitiş zamanı",
+ "AllowedDeveloperCount": "İzin verilen developer sayısı",
+ "UserNameOrEmailAddress": "Kullanıcı adı veya e-posta adresi",
+ "AddOwner": "Owner ekle",
+ "UserName": "Kullanıcı Adı",
+ "Email": "E-Posta",
+ "Developers": "Developers",
+ "AddDeveloper": "Developer Ekle",
+ "Create": "Oluştur",
+ "UserNotFound": "Kullanıcı bulunamadı",
+ "{0}WillBeRemovedFromDevelopers": "{0} kullanıcı adlı developer silinecektir, Onaylıyor musunuz?",
+ "{0}WillBeRemovedFromOwners": "{0} kullanıcı adlı owner silinecektir, Onaylıyor musunuz?",
+ "Computers": "Bilgisayarlar",
+ "UniqueComputerId": "Özgün bilgisayar id",
+ "LastSeenDate": "Son görülme tarihi",
+ "{0}Computer{1}WillBeRemovedFromRecords": "{0} kullanıcı isimli kullanıcının bilgisayarı ({1}) kayıtlardan kaldırılacaktır",
+ "OrganizationDeletionWarningMessage": "Organizasyon silinecektir.",
+ "DeletingLastOwnerWarningMessage": "Bir organizasyon en az bir ownera sahip olmalıdır! Bu nedenle bu ownerı kaldıramazsınız",
+ "This{0}AlreadyExistInThisOrganization": "{0} zaten bu organizasyonda bulunmaktadır",
+ "AreYouSureYouWantToDeleteAllComputers": "Tüm bilgisayaları silmek istediğinize emin misiniz?",
+ "DeleteAll": "Tümünü sil",
+ "DoYouWantToCreateNewUser": "Yeni kullanıcı oluşturmak istiyor musunuz?",
+ "MasterModules": "Master Modüller",
+ "OrganizationName": "Organizasyon adı",
+ "OrganizationNamePlaceholder": "Organizasyon adı...",
+ "UsernameOrEmail": "Kullanıcı adı veya e-posta",
+ "UsernameOrEmailPlaceholder": "Kullanıcı adı veya e-posta",
+ "Member": "Üye",
+ "PurchaseOrderNo": "Satın alma sipariş no",
+ "QuotationDate": "Fiyatlandırma tarihi",
+ "CompanyName": "Şirket adı",
+ "CompanyAddress": "Şirket adresi",
+ "Price": "Fiyat",
+ "DiscountText": "İndirim metni",
+ "DiscountQuantity": "İndirim miktarı",
+ "DiscountPrice": "İndirim fiyatı",
+ "Quotation": "Fiyatlandırma",
+ "ExtraText": "Eksta metin",
+ "ExtraAmount": "Eksta miktar",
+ "DownloadQuotation": "Fiyatlandırmayı İndir",
+ "Invoice": "Fatura",
+ "TaxNumber": "Vergi Numarası",
+ "InvoiceNumber": "Fatura Numarası",
+ "InvoiceDate": "Fatura Tarihi",
+ "InvoiceNote": "Fatura Notu",
+ "Quantity": "Miktar",
+ "AddProduct": "Ürün Ekle",
+ "AddProductWarning": "Ürün eklemelisiniz!",
+ "TotalPrice": "Toplam Fiyat",
+ "Generate": "Üret",
+ "MissingQuantityField": "Miktar alanı zorunludur!",
+ "MissingPriceField": "Fiyat alanı zorunludur!",
+ "CodeUsageStatus": "Statü",
+ "Country": "Ülke",
+ "DeveloperCount": "Developer Sayısı",
+ "RequestCode": "Talep Kodu",
+ "WebSite": "Web Sitesi",
+ "GithubUsername": "Github Kullanıcı adı",
+ "PhoneNumber": "Telefon Numarası",
+ "ProjectDescription": "Proje Açıklaması",
+ "Referrer": "Yönlendiren",
+ "DiscountRequests": "İndirim Talebi",
+ "Copylink": "Kopyalama Linki",
+ "Disable": "Devre Dışı Bırak",
+ "Enable": "Etkinleştir",
+ "EnableSendEmail": "E-Posta Göndermeyi Etkinleştir",
+ "SendEmail": "E-Posta Gönder",
+ "SuccessfullyDisabled": "Başarıyla Devre Dışı Bırakıldı",
+ "SuccessfullyEnabled": "Başarıyla Etkinleştirildi",
+ "EmailSent": "E-Posta Gönderildi",
+ "SuccessfullySent": "Başarıyla Gönderildi",
+ "SuccessfullyDeleted": "Başarıyla Silindi",
+ "DiscountRequestDeletionWarningMessage": "İndirim talebi silinecektir",
+ "BusinessType": "İş tipi",
+ "TotalQuestionCount": "Toplam soru sayısı",
+ "RemainingQuestionCount": "Kalan soru sayısı",
+ "TotalQuestionMustBeGreaterWarningMessage": "Toplam soru sayısı kalan soru sayısından büyük olmalıdır!",
+ "QuestionCountsMustBeGreaterThanZero": "Toplam soru sayısı ve kalan soru sayısı sıfır veya sıfırdan daha büyük olmalıdır!",
+ "UnlimitedQuestionCount": "Sınırsız soru sayısı"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/tr.json
index 767346cd5e..1a25bde775 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/tr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Base/Localization/Resources/tr.json
@@ -1,4 +1,4 @@
-{
+{
"culture": "tr",
"texts": {
"Volo.AbpIo.Domain:010004": "Maksimum üye sayısı aşıldı!",
@@ -18,12 +18,14 @@
"ReadyToGetStarted?": "Başlamaya hazır mısın?",
"JoinOurCommunity": "Topluluğumuza katılın",
"GetStartedUpper": "BAŞLAYIN",
+ "ForkMeOnGitHub": "Fork me on GitHub",
"Features": "Özellikler",
"GetStarted": "Başlayın",
"Documents": "Dokümanlar",
"Community": "Topluluk",
"ContributionGuide": "Katkı Rehberi",
"Blog": "Blog",
+ "Commercial": "Ticari",
"SeeDocuments": "Dokümanlara Göz Atın"
}
-}
+}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json
index 77dab7302e..90db761f1b 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json
@@ -1,4 +1,4 @@
-{
+{
"culture": "tr",
"texts": {
"OrganizationManagement": "Organizasyon yönetimi",
@@ -6,6 +6,8 @@
"Volo.AbpIo.Commercial:010003": "Bu organizasyonda yetkili değilsiniz!",
"OrganizationNotFoundMessage": "Organizasyon bulunamadı!",
"DeveloperCount": "Yazılımcı sayısı",
+ "QuestionCount": "Kalan / toplam sorular",
+ "Unlimited": "Sınırsız",
"Owners": "Yetkili sayısı",
"AddMember": "Üye ekle",
"AddOwner": "Yetkili ekle",
@@ -19,12 +21,15 @@
"StartDate": "Başlangıç tarihi",
"EndDate": "bitiş tarihi",
"Modules": "Modüller",
- "Volo.AbpIo.Commercial:010004": "Kullanıcı bulunamadı! İlgili kullanıcının daha önceden sisteme kayıt olmuş olması gerekiyor.",
"LicenseExtendMessage": "Lisans bitiş tarihiniz {0} tarihine kadar uzatıldı",
"LicenseUpgradeMessage": "Lisansınız {0} lisansa yükseltildi",
"LicenseAddDeveloperMessage": "Lisansınıza {0} geliştirici eklendi",
- "MyOrganizations": "Organizasyonlarım",
- "ApiKey": "API anahtarı",
- "UserNameNotFound": "{0} kullanıcı adı ile bir kullanıcı yok"
+ "Volo.AbpIo.Commercial:010004": "Kullanıcı bulunamadı! İlgili kullanıcının daha önceden sisteme kayıt olmuş olması gerekiyor.",
+ "MyOrganizations": "Organizasyonlarım",
+ "ApiKey": "API anahtarı",
+ "UserNameNotFound": "{0} kullanıcı adı ile bir kullanıcı yok",
+ "SuccessfullyAddedToNewsletter": "Bültenimize abone olduğunuz için teşekkürler!",
+ "MyProfile": "Profilim",
+ "EmailNotValid": "Lütfen uygun bir e-posta adresi giriniz"
}
}
\ No newline at end of file
diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json
index 5af6a13c50..5f423e940b 100644
--- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json
+++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/tr.json
@@ -1,5 +1,161 @@
{
"culture": "tr",
"texts": {
+ "GetStarted": "Başlamak - Başlangıç Templateleri",
+ "Create": "Oluştur",
+ "NewProject": "Yeni Proje",
+ "DirectDownload": "Doğrudan İndir",
+ "ProjectName": "Proje ismi",
+ "ProjectType": "Proje tipi",
+ "DatabaseProvider": "Veritabanı sağlayacısı",
+ "NTier": "N-Tier",
+ "IncludeUserInterface": "Kullanıcı arayüzünü dahil et",
+ "CreateNow": "Şimdi oluştur",
+ "TheStartupProject": "Başlangıç projesi",
+ "Tutorial": "Öğretici",
+ "UsingCLI": "CLI Kullanmak",
+ "SeeDetails": "Detayları Görüntüle",
+ "AbpShortDescription": "ABP modern web uygulamaları geliştirmek için eksiksiz bir mimari ve günlü bir altyapıdır! Size SOLID geliştirme tecrübelerini sunmak için en iyi uygulama ve kuralları takip eder.",
+ "SourceCodeUpper": "KAYNAK KOD",
+ "LatestReleaseLogs": "Son release kayıtları",
+ "Infrastructure": "Altyapı",
+ "Architecture": "Mimari",
+ "Modular": "Modüler",
+ "DontRepeatYourself": "Kendini Tekrar Etme",
+ "DeveloperFocused": "Developer Odaklı",
+ "FullStackApplicationInfrastructure": "Full stack uygulama altyapısı",
+ "DomainDrivenDesign": "Domain Driven Design",
+ "DomainDrivenDesignExplanation": "DDD paterni ve prensiplerinden yola çıkarak dizayn edildi ve geliştirildi. Uygulamanız için katmanlı bir model sunmaktadır.",
+ "Authorization": "Yetkilendirme",
+ "AuthorizationExplanation": "Kullanıcı, rol ve ayrıntılı izin sistemi ile modern yetkilendirme. Microsoft Identity library üzerine kurulmuştur.",
+ "MultiTenancy": "Multi-Tenancy",
+ "MultiTenancyExplanationShort": "SaaS uygulamaları kolaylaştı! Veritababından kullanıcı arayüzüne entegre edilmiş multi-tenancy",
+ "CrossCuttingConcerns": "Cross Cutting Concerns",
+ "CrossCuttingConcernsExplanationShort": "Yetkilendirme, validasyon, hata yakalama, caching, audit logging, işlem yönetimi ve bunun gibi konular için eksiksiz altyapı.",
+ "BuiltInBundlingMinification": "Hazır Paketleme & Küçültme",
+ "BuiltInBundlingMinificationExplanation": "Paketleme ve küçültmek için external araçları kullanmayı bırakın. ABP daha basit, dinamik, güçlü, modüler ve hazır yolları öneriyor.",
+ "VirtualFileSystem": "Sanal Dosya Sistemi",
+ "VirtualFileSystemExplanation": "Sayfaları, scriptleri, stilleri, resimleri... paketlere/kütüpanelere gömün ve farklı uygulamalarda yeniden kullanın. ",
+ "Theming": "Theming",
+ "ThemingExplanationShort": "Bootstrap tabanlı standart kullanıcı arayüzlerini kullan ve kişiselleştir veya kendin yeni bir tane oluştur.",
+ "BootstrapTagHelpersDynamicForms": "Bootstrap Tag Helpers & Dinamik Formlar",
+ "BootstrapTagHelpersDynamicFormsExplanation": "Bootstrap komponentlerinin tekrar eden detaylarını manuel olarak yazmak yerine, Bu işlemi basitleştirmek ve iyileştirme avantajından faydalanmak için ABP'nin tag helperlarını kullanın. Dinamik form bir C# sınıfından model olarak eksiksik form oluşturabilir.",
+ "HTTPAPIsDynamicProxies": "HTTP APIs & Dynamic Proxies",
+ "HTTPAPIsDynamicProxiesExplanation": "Application servislerini otomatik olarak Rest stil Http API olarak ayarlayın ve dinamaik Javascript & C# proxyler ile kullanın.",
+ "CompleteArchitectureInfo": "Bakım yapılabilir yazılım çözümleri üretmek için modern mimari.",
+ "DomainDrivenDesignBasedLayeringModelExplanation": "DDD tabanlı bir katmanlı mimari geliştirmek ve bakım yapılabilir bir kod altyapısı inşaa etmek için size yardım eder.",
+ "DomainDrivenDesignBasedLayeringModelExplanationCont": "DDD patern ve prensiplerinden yola çıkarak uygulamanızı geliştirmeye yardımcı olmak için başlanıç templateler, soyutlamalar, base sınıflar, servisler, dokümantasyon ve rehberlik sağlar. ",
+ "MicroserviceCompatibleModelExplanation": "Core framework & pre-build modüller mikroservis mimari göz önünde bulundurularak dizayn edildi.",
+ "MicroserviceCompatibleModelExplanationCont": "Microservice çözümlerini daha kolay geliştirmek için altyapı, entegrasyon, örnekler ve dokümantasyon sunarken eğer bir tek parça uygulama istiyorsanız ek karmaşıklık getirmez.",
+ "ModularInfo": "ABP yeniden kullanılabilir uygulama modülleri geliştirebilmenize izin veren eksiksiz modüler sistem sunar.",
+ "PreBuiltModulesThemes": "Pre-Built Modüller & Temalar",
+ "PreBuiltModulesThemesExplanation": "Açık kaynak ve ticari modüller & temalar iş uygulamanızda kullanıma hazırdır.",
+ "NuGetNPMPackages": "NUGET & NPM Packages",
+ "NuGetNPMPackagesExplanation": "NUGET & NPM paketleri olarak dağıtılmıştır. Yüklemek ve güncellemek kolaydır.",
+ "ExtensibleReplaceable": "Genişletilebilir/Değiştirilebilir",
+ "ExtensibleReplaceableExplanation": "Tüm sevisler & modüller genişletilebilirlik göz önünde bulundurularak dizayn edildi. Servislerin, sayfaların stillerin, komponentlerin vb. yerlerini değiştirebilirsizinz.",
+ "CrossCuttingConcernsExplanation2": "Kodunu daha temiz tut ve kendi uygulama koduna odaklan.",
+ "CrossCuttingConcernsExplanation3": "Ortak uygulama isterlerini tekrar ve tekrar geliştirmek için zaman harcamayın.",
+ "AuthenticationAuthorization": "Kimlik Doğrulama & Yetkilendirme",
+ "ExceptionHandling": "Hata yakalama",
+ "Validation": "Validasyon",
+ "DatabaseConnection": "Veritabanı bağlantısı",
+ "TransactionManagement": "İşlem yönetimi",
+ "AuditLogging": "Audit Logging",
+ "Caching": "Caching",
+ "Multitenancy": "Multitenancy",
+ "DataFiltering": "Date filtreleme",
+ "ConventionOverConfiguration": "Yapılandırma Üzerinde Kurallar",
+ "ConventionOverConfigurationExplanation": "ABP minimal veya sıfır yapılandırma ile ortak uygulama kurallarını varsayılan olarak uygular.",
+ "ConventionOverConfigurationExplanationList1": "Dependency injection için bilinen servisler otomatik olarak kaydedilir.",
+ "ConventionOverConfigurationExplanationList2": "Application servisler isimlerdirme kuralları ile HTTP API ler olarak uygulanır.",
+ "ConventionOverConfigurationExplanationList3": "C# ve JavaScript için dinamik HTTP istemci proxyleri yaratır.",
+ "ConventionOverConfigurationExplanationList4": "Entityleriniz için varsayılaan repositoriler sunar.",
+ "ConventionOverConfigurationExplanationList5": "Her web request veya application servis metodu için Unit of Work işlemini yönetir.",
+ "ConventionOverConfigurationExplanationList6": "Entityleriniz için oluşturma, güncelleme & silme işlemlerini yayınlar.",
+ "BaseClasses": "Ana Sınıflar",
+ "BaseClassesExplanation": "Ortak uygulama paternleri için pre-built ana sınıflar.",
+ "DeveloperFocusedExplanation": "ABP developerlar içindir.",
+ "DeveloperFocusedExplanationCont": "İhtiyacınız olduğunda düşük seviyede çalışmanızı kısıtlamadan günlük yazılım geliştirmenizi basitleştirmeyi amaçlar.",
+ "SeeAllFeatures": "Tüm Özellikleri Görüntüle",
+ "CLI_CommandLineInterface": "CLI (Command Line Interface)",
+ "CLI_CommandLineInterfaceExplanation": "CLI yeni proje oluşturma ve uygulamanıza modüller ekleme işlemlerini otomatik hale getirir.",
+ "StartupTemplates": "Başlangıç Templateler",
+ "StartupTemplatesExplanation": "Çeşitli başlangıç templateleri size geliştirme başlatmak için tam yapılandırılmış bir çözüm sağlar.",
+ "BasedOnFamiliarTools": "Bilinen Araçlara Dayalı ",
+ "BasedOnFamiliarToolsExplanation": "Zaten bildiğiniz popüler araçlar ile geliştirilme ve egtegre edilmiştir. Düşük öğrenme eğrisi, koaly adaptasyon, rahat geliştirme.",
+ "ORMIndependent": "ORM Bağımsız",
+ "ORMIndependentExplanation": "",
+ "Features": "ABP Framework Özelliklerini Keşfet",
+ "ABPCLI": "ABP CLI",
+ "Modularity": "Modülerlik",
+ "BootstrapTagHelpers": "Bootstrap Tag Helpers",
+ "DynamicForms": "Dinamik Formlar",
+ "BundlingMinification": "Paketleme & Küçültme",
+ "BackgroundJobs": "Arkaplan İşleri",
+ "DDDInfrastructure": "DDD altyapısı",
+ "DomainDrivenDesignInfrastructure": "Domain Driven Design Altyapısı",
+ "AutoRESTAPIs": "Otomatik REST APIler",
+ "DynamicClientProxies": "Dinamik Client Proxies",
+ "DistributedEventBus": "Dağıtılmış Event Bus",
+ "DistributedEventBusWithRabbitMQIntegration": "RabbitMQ Entegrasyonu ile Dağıtılmış Event Bus",
+ "TestInfrastructure": "Test ALtyapısı",
+ "AuditLoggingEntityHistories": "Audit Logging & Entity Histories",
+ "ObjectToObjectMapping": "Object to Object Mapping",
+ "EmailSMSAbstractions": "E-Posta & SMS Soyutlamaları",
+ "EmailSMSAbstractionsWithTemplatingSupport": "Template Destekli E-Posta & SMS Soyutlamaları",
+ "Localization": "Localization",
+ "SettingManagement": "Ayar Yönetimi",
+ "ExtensionMethods": "Extension Methods",
+ "ExtensionMethodsHelpers": "Extension Methods & Helpers",
+ "AspectOrientedProgramming": "Aspect Oriented Programming",
+ "DependencyInjection": "Dependency Injection",
+ "DependencyInjectionByConventions": "Dependency Injection by Conventions",
+ "ABPCLIExplanation": "ABP CLI (Command Line Interface) ABP tabanlı çözümler ortak işlemleri gerçekleştiren bir komut satırı aracıdır.",
+ "ModularityExplanation": "ABP, entityleri, servisleri, veritabanı entegrasyonu, APIleri, UI komponentleri ve bunun gibi özelliklere sahip olabilecek kendi uygulama modüllerini geliştirmeniz için eksiksiz bir altyapı sağlar. ",
+ "MultiTenancyExplanation": "ABP framework sadece multi-tenant uygulama geliştirmenizi desteklemekle kalmaz aynı zamanda kodunuzun çoğunlukla tenantların birbirinden haberi olmaycak şekilde olmasını sağlar.",
+ "MultiTenancyExplanation2": "Anlık tenant'ı otomatik olarak belirleybilir, farklı tenantların verilerini birbirlerinden izole edebilir.",
+ "MultiTenancyExplanation3": "Tek bir veritabanını, her tenant için ayrı bir veritabanını ve hibrid yaklaşımları destekler.",
+ "MultiTenancyExplanation4": "Sen kendi uygulama kodunu odaklan ve bırak framework sizin adınıza multi-tenancy üstesinden gelsin.",
+ "BootstrapTagHelpersExplanation": "Bootstrap komponentlerinin tekrar eden detaylarını manuel olarak yazmak yerine, Bu işlemi basitleştirmek ve iyileştirme avantajından faydalanmak için ABP'nin tag helperlarını kullanın. Dinamik form bir C# sınıfından model olarak eksiksik form oluşturabilir.",
+ "DynamicFormsExplanation": "Dinamik form & input tag helpers bir C# sınıfından model olarak eksiksik form oluşturabilir.",
+ "AuthenticationAuthorizationExplanation": "ASP.NET Core Identity & IdentityServer4 ile entegre edilmiş zengin kimlik doğrulama ve yetkilendirme opsiyonları. Genişletilebilir ve detaylandırılabilr bir izin sistemi sunar.",
+ "CrossCuttingConcernsExplanation": "Tüm bu ortak şeyleri geliştirmek için kendini sürekli tekrar etme. Kendi iş koduna odaklan ve bırak ABP bunları kurallar ile otomatik hale getirsin.",
+ "DatabaseConnectionTransactionManagement": "Veritabanı Bğlantısı & İşlem Yönetimi",
+ "CorrelationIdTracking": "Correlation-Id Tracking",
+ "BundlingMinificationExplanation": "ABP daha basit, dinamik, güçlü, modüler ve hazır paketlenmiş ve küçültülmüş sistemi öneriyor.",
+ "VirtualFileSystemnExplanation": "Sanal Dosya Sistemi fiziksel olarak disk üzerinde var olmayan dosyalarını yönetmeyi mümkün kılmaktadır. Bunlar genellikle önceden assemblyler içerisinde gömülü olan(js,css,image,cshtml..) dosyalardır ve bunlar fiziksel dosylar gibi runtimeda kullanılır.",
+ "ThemingExplanation": "Theming sistem son Bootstrap Framework tabanlı ortak bir kütüphane ve layout tanımlayarak uygulamanızı & modüllerini bağımsız olarak geliştirmenizi sağlamaktadır.",
+ "DomainDrivenDesignInfrastructureExplanation": "Domain Driven Design pattern ve prensiplerine dayalı katmanlı uygulama geliştirmek için eksiksiz bit altyapı",
+ "Specification": "Specification",
+ "Repository": "Repository",
+ "DomainService": "Domain Service",
+ "ValueObject": "Value Object",
+ "ApplicationService": "Application Service",
+ "DataTransferObject": "Data Transfer Object",
+ "AggregateRootEntity": "Aggregate Root, Entity",
+ "AutoRESTAPIsExplanation": "ABP, application servislerinizi otomatik olarak API Controller olarak kurallı bir şekilde yapılandırabilir.",
+ "DynamicClientProxiesExplanation": "Apilerinizi, JavaScript ve C# clients tarafından kolaylıkla kullanın.",
+ "DistributedEventBusWithRabbitMQIntegrationExplanation": "Easily publish & consume distributed events using built-in Distributed Event Bus with RabbitMQ integration available.",
+ "TestInfrastructureExplanation": "The framework has been developed unit & integration testing in mind. Provides you base classes to make it easier. Startup templates come with pre-configured for testing.",
+ "AuditLoggingEntityHistoriesExplanation": "",
+ "EmailSMSAbstractionsWithTemplatingSupportExplanation": "",
+ "LocalizationExplanation": "",
+ "SettingManagementExplanation": "",
+ "ExtensionMethodsHelpersExplanation": "",
+ "AspectOrientedProgrammingExplanation": "",
+ "DependencyInjectionByConventionsExplanation": "",
+ "DataFilteringExplanation": "",
+ "PublishEvents": "Publish Events",
+ "HandleEvents": "Handle Events",
+ "AndMore": "",
+ "Code": "Code",
+ "Result": "Sonuç",
+ "SeeTheDocumentForMoreInformation": "See the {0} document for more information",
+ "IndexPageHeroSection": "open sourceWeb Application Framework for asp.net core",
+ "UiFramework": "UI Framework",
+ "EmailAddress": "E-Posta Adresi",
+ "Mobile": "Mobil",
+ "ReactNative": "React Native"
}
}
\ No newline at end of file
diff --git a/docs/en/Blob-Storing.md b/docs/en/Blob-Storing.md
index 1cb8acb78c..2b49a896cd 100644
--- a/docs/en/Blob-Storing.md
+++ b/docs/en/Blob-Storing.md
@@ -169,7 +169,7 @@ public class ProfileAppService : ApplicationService
If you don't use the generic argument and directly inject the `IBlobContainer` (as explained before), you get the default container. Another way of injecting the default container is using `IBlobContainer`, which returns exactly the same container.
-The name of the default container is `Default`.
+The name of the default container is `default`.
### Named Containers
diff --git a/docs/en/Distributed-Event-Bus-RabbitMQ-Integration.md b/docs/en/Distributed-Event-Bus-RabbitMQ-Integration.md
index dc3d5c172f..9587a111bf 100644
--- a/docs/en/Distributed-Event-Bus-RabbitMQ-Integration.md
+++ b/docs/en/Distributed-Event-Bus-RabbitMQ-Integration.md
@@ -1,3 +1,134 @@
# Distributed Event Bus RabbitMQ Integration
-TODO
\ No newline at end of file
+> This document explains **how to configure the [RabbitMQ](https://www.rabbitmq.com/)** as the distributed event bus provider. See the [distributed event bus document](Distributed-Event-Bus.md) to learn how to use the distributed event bus system
+
+## Installation
+
+Use the ABP CLI to add [Volo.Abp.EventBus.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.EventBus.RabbitMQ) NuGet package to your project:
+
+* Install the [ABP CLI](https://docs.abp.io/en/abp/latest/CLI) if you haven't installed before.
+* Open a command line (terminal) in the directory of the `.csproj` file you want to add the `Volo.Abp.EventBus.RabbitMQ` package.
+* Run `abp add-package Volo.Abp.EventBus.RabbitMQ` command.
+
+If you want to do it manually, install the [Volo.Abp.EventBus.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.EventBus.RabbitMQ) NuGet package to your project and add `[DependsOn(typeof(AbpEventBusRabbitMqModule))]` to the [ABP module](Module-Development-Basics.md) class inside your project.
+
+## Configuration
+
+You can configure using the standard [configuration system](Configuration.md), like using the `appsettings.json` file, or using the [options](Options.md) classes.
+
+### `appsettings.json` file configuration
+
+This is the simplest way to configure the RabbitMQ settings. It is also very strong since you can use any other configuration source (like environment variables) that is [supported by the AspNet Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/).
+
+**Example: The minimal configuration to connect to a local RabbitMQ server with default configurations**
+
+````json
+{
+ "RabbitMQ": {
+ "EventBus": {
+ "ClientName": "MyClientName",
+ "ExchangeName": "MyExchangeName"
+ }
+ }
+}
+````
+
+* `ClientName` is the name of this application, which is used as the **queue name** on the RabbitMQ.
+* `ExchangeName` is the **exchange name**.
+
+See [the RabbitMQ document](https://www.rabbitmq.com/dotnet-api-guide.html#exchanges-and-queues) to understand these options better.
+
+#### Connections
+
+If you need to connect to another server than the localhost, you need to configure the connection properties.
+
+**Example: Specify the host name (as an IP address)**
+
+````json
+{
+ "RabbitMQ": {
+ "Connections": {
+ "Default": {
+ "HostName": "123.123.123.123"
+ }
+ },
+ "EventBus": {
+ "ClientName": "MyClientName",
+ "ExchangeName": "MyExchangeName"
+ }
+ }
+}
+````
+
+Defining multiple connections is allowed. In this case, you can specify the connection that is used for the event bus.
+
+**Example: Declare two connections and use one of them for the event bus**
+
+````json
+{
+ "RabbitMQ": {
+ "Connections": {
+ "Default": {
+ "HostName": "123.123.123.123"
+ },
+ "SecondConnection": {
+ "HostName": "321.321.321.321"
+ }
+ },
+ "EventBus": {
+ "ClientName": "MyClientName",
+ "ExchangeName": "MyExchangeName",
+ "ConnectionName": "SecondConnection"
+ }
+ }
+}
+````
+
+This allows you to use multiple RabbitMQ server in your application, but select one of them for the event bus.
+
+You can use any of the [ConnectionFactry](http://rabbitmq.github.io/rabbitmq-dotnet-client/api/RabbitMQ.Client.ConnectionFactory.html#properties) properties as the connection properties.
+
+**Example: Specify the connection port**
+
+````csharp
+{
+ "RabbitMQ": {
+ "Connections": {
+ "Default": {
+ "HostName": "123.123.123.123",
+ "Port": "5672"
+ }
+ }
+ }
+}
+````
+
+### The Options Classes
+
+`AbpRabbitMqOptions` and `AbpRabbitMqEventBusOptions` classes can be used to configure the connection strings and event bus options for the RabbitMQ.
+
+You can configure this options inside the `ConfigureServices` of your [module](Module-Development-Basics.md).
+
+**Example: Configure the connection**
+
+````csharp
+Configure(options =>
+{
+ options.Connections.Default.UserName = "user";
+ options.Connections.Default.Password = "pass";
+ options.Connections.Default.HostName = "123.123.123.123";
+ options.Connections.Default.Port = 5672;
+});
+````
+
+**Example: Configure the client and exchange names**
+
+````csharp
+Configure(options =>
+{
+ options.ClientName = "TestApp1";
+ options.ExchangeName = "TestMessages";
+});
+````
+
+Using these options classes can be combined with the `appsettings.json` way. Configuring an option property in the code overrides the value in the configuration file.
\ No newline at end of file
diff --git a/docs/en/Distributed-Event-Bus.md b/docs/en/Distributed-Event-Bus.md
index 03beb814d2..947b0f3142 100644
--- a/docs/en/Distributed-Event-Bus.md
+++ b/docs/en/Distributed-Event-Bus.md
@@ -1,3 +1,299 @@
# Distributed Event Bus
-TODO
\ No newline at end of file
+Distributed Event bus system allows to **publish** and **subscribe** to events that can be **transferred across application/service boundaries**. You can use the distributed event bus to asynchronously send and receive messages between **microservices** or **applications**.
+
+## Providers
+
+Distributed event bus system provides an **abstraction** that can be implemented by any vendor/provider. There are two providers implemented out of the box:
+
+* `LocalDistributedEventBus` is the default implementation that implements the distributed event bus to work as in-process. Yes! The **default implementation works just like the [local event bus](Local-Event-Bus.md)**, if you don't configure a real distributed provider.
+* `RabbitMqDistributedEventBus` implements the distributed event bus with the [RabbitMQ](https://www.rabbitmq.com/). See the [RabbitMQ integration document](Distributed-Event-Bus-RabbitMQ-Integration.md) to learn how to configure it.
+
+Using a local event bus as default has a few important advantages. The most important one is that: It allows you to write your code compatible to distributed architecture. You can write a monolithic application now that can be split into microservices later. It is a good practice to communicate between bounded contexts (or between application modules) via distributed events instead of local events.
+
+For example, [pre-built application modules](Modules/Index.md) is designed to work as a service in a distributed system while they can also work as a module in a monolithic application without depending an external message broker.
+
+## Publishing Events
+
+There are two ways of publishing distributed events explained in the following sections.
+
+### IDistributedEventBus
+
+`IDistributedEventBus` can be [injected](Dependency-Injection.md) and used to publish a distributed event.
+
+**Example: Publish a distributed event when the stock count of a product changes**
+
+````csharp
+using System;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.EventBus.Distributed;
+
+namespace AbpDemo
+{
+ public class MyService : ITransientDependency
+ {
+ private readonly IDistributedEventBus _distributedEventBus;
+
+ public MyService(IDistributedEventBus distributedEventBus)
+ {
+ _distributedEventBus = distributedEventBus;
+ }
+
+ public virtual async Task ChangeStockCountAsync(Guid productId, int newCount)
+ {
+ await _distributedEventBus.PublishAsync(
+ new StockCountChangedEvent
+ {
+ ProductId = productId,
+ NewCount = newCount
+ }
+ );
+ }
+ }
+}
+````
+
+`PublishAsync` method gets a single parameter: the event object, which is responsible to hold the data related to the event. It is a simple plain class:
+
+````csharp
+using System;
+
+namespace AbpDemo
+{
+ [EventName("MyApp.Product.StockChange")]
+ public class StockCountChangedEto
+ {
+ public Guid ProductId { get; set; }
+
+ public int NewCount { get; set; }
+ }
+}
+````
+
+Even if you don't need to transfer any data, you need to create a class (which is an empty class in this case).
+
+> `Eto` is a suffix for **E**vent **T**ransfer **O**bjects we use by convention. While it is not required, we find it useful to identify such event classes (just like [DTOs](Data-Transfer-Objects.md) on the application layer).
+
+#### Event Name
+
+`EventName` attribute is optional, but suggested. If you don't declare it, the event name will be the full name of the event class, `AbpDemo.StockCountChangedEto` in this case.
+
+#### About Serialization for the Event Objects
+
+Event transfer objects **must be serializable** since they will be serialized/deserialized to JSON or other format when it is transferred to out of the process.
+
+Avoid circular references, polymorphism, private setters and provide default (empty) constructors if you have any other constructor as a good practice (while some serializers may tolerate it), just like the DTOs.
+
+### Inside Entity / Aggregate Root Classes
+
+[Entities](Entities.md) can not inject services via dependency injection, but it is very common to publish distributed events inside entity / aggregate root classes.
+
+**Example: Publish a distributed event inside an aggregate root method**
+
+````csharp
+using System;
+using Volo.Abp.Domain.Entities;
+
+namespace AbpDemo
+{
+ public class Product : AggregateRoot
+ {
+ public string Name { get; set; }
+
+ public int StockCount { get; private set; }
+
+ private Product() { }
+
+ public Product(Guid id, string name)
+ : base(id)
+ {
+ Name = name;
+ }
+
+ public void ChangeStockCount(int newCount)
+ {
+ StockCount = newCount;
+
+ //ADD an EVENT TO BE PUBLISHED
+ AddDistributedEvent(
+ new StockCountChangedEto
+ {
+ ProductId = Id,
+ NewCount = newCount
+ }
+ );
+ }
+ }
+}
+````
+
+`AggregateRoot` class defines the `AddDistributedEvent` to add a new distributed event, that is published when the aggregate root object is saved (created, updated or deleted) into the database.
+
+> If an entity publishes such an event, it is a good practice to change the related properties in a controlled manner, just like the example above - `StockCount` can only be changed by the `ChangeStockCount` method which guarantees publishing the event.
+
+#### IGeneratesDomainEvents Interface
+
+Actually, adding distributed events are not unique to the `AggregateRoot` class. You can implement `IGeneratesDomainEvents` for any entity class. But, `AggregateRoot` implements it by default and makes it easy for you.
+
+> It is not suggested to implement this interface for entities those are not aggregate roots, since it may not work for some database providers for such entities. It works for EF Core, but not works for MongoDB for example.
+
+#### How It Was Implemented?
+
+Calling the `AddDistributedEvent` doesn't immediately publish the event. The event is published when you save changes to the database;
+
+* For EF Core, it is published on `DbContext.SaveChanges`.
+* For MongoDB, it is published when you call repository's `InsertAsync`, `UpdateAsync` or `DeleteAsync` methods (since MongoDB has not a change tracking system).
+
+## Subscribing to Events
+
+A service can implement the `IDistributedEventHandler` to handle the event.
+
+**Example: Handle the `StockCountChangedEto` defined above**
+
+````csharp
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.EventBus.Distributed;
+
+namespace AbpDemo
+{
+ public class MyHandler
+ : IDistributedEventHandler,
+ ITransientDependency
+ {
+ public async Task HandleEventAsync(StockCountChangedEto eventData)
+ {
+ var productId = eventData.ProductId;
+ }
+ }
+}
+````
+
+That's all.
+
+* `MyHandler` is **automatically discovered** by the ABP Framework and `HandleEventAsync` is called whenever a `StockCountChangedEto` event occurs.
+* If you are using a distributed message broker, like RabbitMQ, ABP automatically **subscribes to the event on the message broker**, gets the message, executes the handler.
+* It sends **confirmation (ACK)** to the message broker if the event handler was successfully executed (did not throw any exception).
+
+You can inject any service and perform any required logic here. A single event handler class can **subscribe to multiple events** but implementing the `IDistributedEventHandler` interface for each event type.
+
+> The handler class must be registered to the dependency injection (DI). The sample above uses the `ITransientDependency` to accomplish it. See the [DI document](Dependency-Injection.md) for more options.
+
+## Pre-Defined Events
+
+ABP Framework **automatically publishes** distributed events for **create, update and delete** operations for an [entity](Entities.md) once you configure it.
+
+### Event Types
+
+There are three pre-defined event types:
+
+* `EntityCreatedEto` is published when an entity of type `T` was created.
+* `EntityUpdatedEto` is published when an entity of type `T` was updated.
+* `EntityDeletedEto` is published when an entity of type `T` was deleted.
+
+These types are generics. `T` is actually the type of the **E**vent **T**ransfer **O**bject (ETO) rather than the type of the entity. Because, an entity object can not be transferred as a part of the event data. So, it is typical to define a ETO class for an entity class, like `ProductEto` for `Product` entity.
+
+### Subscribing to the Events
+
+Subscribing to the auto events is same as subscribing a regular distributed event.
+
+**Example: Get notified once a product updated**
+
+````csharp
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Domain.Entities.Events.Distributed;
+using Volo.Abp.EventBus.Distributed;
+
+namespace AbpDemo
+{
+ public class MyHandler :
+ IDistributedEventHandler>,
+ ITransientDependency
+ {
+ public async Task HandleEventAsync(EntityUpdatedEto eventData)
+ {
+ var productId = eventData.Entity.Id;
+ //TODO
+ }
+ }
+}
+````
+
+* `MyHandler` implements the `IDistributedEventHandler>`.
+
+### Configuration
+
+You can configure the `AbpDistributedEntityEventOptions` in the `ConfigureServices` of your [module](Module-Development-Basics.md) to add a selector.
+
+**Example: Configuration samples**
+
+````csharp
+Configure(options =>
+{
+ //Enable for all entities
+ options.AutoEventSelectors.AddAll();
+
+ //Enable for a single entity
+ options.AutoEventSelectors.Add();
+
+ //Enable for all entities in a namespace (and child namespaces)
+ options.AutoEventSelectors.AddNamespace("Volo.Abp.Identity");
+
+ //Custom predicate expression that should return true to select a type
+ options.AutoEventSelectors.Add(
+ type => type.Namespace.StartsWith("MyProject.")
+ );
+});
+````
+
+* The last one provides flexibility to decide if the events should be published for the given entity type. Returns `true` to accept a `Type`.
+
+You can add more than one selector. If one of the selectors match for an entity type, then it is selected.
+
+### Event Transfer Object
+
+Once you enable **auto events** for an entity, ABP Framework starts to publish events on the changes on this entity. If you don't specify a corresponding **E**vent **T**ransfer **O**bject (ETO) for the entity, ABP Framework uses a standard type, named `EntityEto`, which has only two properties:
+
+* `EntityType` (`string`): Full name (including namespace) of the entity class.
+* `KeysAsString` (`string`): Primary key(s) of the changed entity. If it has a single key, this property will be the primary key value. For a composite key, it will contain all keys separated by `,` (comma).
+
+So, you can implement the `IDistributedEventHandler>` to subscribe the events. However, it is not a good approach to subscribe to such a generic event. You can define the corresponding ETO for the entity type.
+
+**Example: Declare to use `ProductEto` for the `Product` entity**
+
+````csharp
+Configure(options =>
+{
+ options.AutoEventSelectors.Add();
+ options.EtoMappings.Add();
+});
+````
+
+This example;
+
+* Adds a selector to allow to publish the create, update and delete events for the `Product` entity.
+* Configure to use the `ProductEto` as the event transfer object to publish for the `Product` related events.
+
+Distributed event system use the [object to object mapping](Object-To-Object-Mapping.md) system to map `Product` objects to `ProductEto` objects. So, you need to configure the mapping. You can check the object to object mapping document for all options, but the following example shows how to configure it with the [AutoMapper](https://automapper.org/) library.
+
+**Example: Configure `Product` to `ProductEto` mapping using the AutoMapper**
+
+````csharp
+using System;
+using AutoMapper;
+using Volo.Abp.Domain.Entities.Events.Distributed;
+
+namespace AbpDemo
+{
+ [AutoMap(typeof(Product))]
+ public class ProductEto : EntityEto
+ {
+ public Guid Id { get; set; }
+ public string Name { get; set; }
+ }
+}
+````
+
+This example uses the `AutoMap` attribute of the AutoMapper to configure the mapping. You could create a profile class instead. Please refer to the AutoMapper document for more options.
\ No newline at end of file
diff --git a/docs/en/Event-Bus.md b/docs/en/Event-Bus.md
index cf2b57c018..a0e6859465 100644
--- a/docs/en/Event-Bus.md
+++ b/docs/en/Event-Bus.md
@@ -1,3 +1,10 @@
# Event Bus
-TODO
\ No newline at end of file
+An event bus is a mediator that transfers a message from a sender to a receiver. In this way, it provides a loosely coupled communication way between objects, services and applications.
+
+## Event Bus Types
+
+ABP Framework provides two type of event buses;
+
+* **[Local Event Bus](Local-Event-Bus.md)** is suitable for in-process messaging.
+* **[Distributed Event Bus](Distributed-Event-Bus.md)** is suitable for inter-process messaging, like microservices publishing and subscribing to distributed events.
\ No newline at end of file
diff --git a/docs/en/Local-Event-Bus.md b/docs/en/Local-Event-Bus.md
index 859ec8d28e..d0f494faea 100644
--- a/docs/en/Local-Event-Bus.md
+++ b/docs/en/Local-Event-Bus.md
@@ -1,3 +1,227 @@
# Local Event Bus
-TODO
\ No newline at end of file
+The Local Event Bus allows services to publish and subscribe to **in-process events**. That means it is suitable if two services (publisher and subscriber) are running in the same process.
+
+## Publishing Events
+
+There are two ways of publishing local events explained in the following sections.
+
+### ILocalEventBus
+
+`ILocalEventBus` can be [injected](Dependency-Injection.md) and used to publish a local event.
+
+**Example: Publish a local event when the stock count of a product changes**
+
+````csharp
+using System;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.EventBus.Local;
+
+namespace AbpDemo
+{
+ public class MyService : ITransientDependency
+ {
+ private readonly ILocalEventBus _localEventBus;
+
+ public MyService(ILocalEventBus localEventBus)
+ {
+ _localEventBus = localEventBus;
+ }
+
+ public virtual async Task ChangeStockCountAsync(Guid productId, int newCount)
+ {
+ //TODO: IMPLEMENT YOUR LOGIC...
+
+ //PUBLISH THE EVENT
+ await _localEventBus.PublishAsync(
+ new StockCountChangedEvent
+ {
+ ProductId = productId,
+ NewCount = newCount
+ }
+ );
+ }
+ }
+}
+````
+
+`PublishAsync` method gets a single parameter: the event object, which is responsible to hold the data related to the event. It is a simple plain class:
+
+````csharp
+using System;
+
+namespace AbpDemo
+{
+ public class StockCountChangedEvent
+ {
+ public Guid ProductId { get; set; }
+
+ public int NewCount { get; set; }
+ }
+}
+````
+
+Even if you don't need to transfer any data, you need to create a class (which is an empty class in this case).
+
+### Inside Entity / Aggregate Root Classes
+
+[Entities](Entities.md) can not inject services via dependency injection, but it is very common to publish local events inside entity / aggregate root classes.
+
+**Example: Publish a local event inside an aggregate root method**
+
+````csharp
+using System;
+using Volo.Abp.Domain.Entities;
+
+namespace AbpDemo
+{
+ public class Product : AggregateRoot
+ {
+ public string Name { get; set; }
+
+ public int StockCount { get; private set; }
+
+ private Product() { }
+
+ public Product(Guid id, string name)
+ : base(id)
+ {
+ Name = name;
+ }
+
+ public void ChangeStockCount(int newCount)
+ {
+ StockCount = newCount;
+
+ //ADD an EVENT TO BE PUBLISHED
+ AddLocalEvent(
+ new StockCountChangedEvent
+ {
+ ProductId = Id,
+ NewCount = newCount
+ }
+ );
+ }
+ }
+}
+````
+
+`AggregateRoot` class defines the `AddLocalEvent` to add a new local event, that is published when the aggregate root object is saved (created, updated or deleted) into the database.
+
+> If an entity publishes such an event, it is a good practice to change the related properties in a controlled manner, just like the example above - `StockCount` can only be changed by the `ChangeStockCount` method which guarantees publishing the event.
+
+#### IGeneratesDomainEvents Interface
+
+Actually, adding local events are not unique to the `AggregateRoot` class. You can implement `IGeneratesDomainEvents` for any entity class. But, `AggregateRoot` implements it by default and makes it easy for you.
+
+> It is not suggested to implement this interface for entities those are not aggregate roots, since it may not work for some database providers for such entities. It works for EF Core, but not works for MongoDB for example.
+
+#### How It Was Implemented?
+
+Calling the `AddLocalEvent` doesn't immediately publish the event. The event is published when you save changes to the database;
+
+* For EF Core, it is published on `DbContext.SaveChanges`.
+* For MongoDB, it is published when you call repository's `InsertAsync`, `UpdateAsync` or `DeleteAsync` methods (since MongoDB has not a change tracking system).
+
+## Subscribing to Events
+
+A service can implement the `ILocalEventHandler` to handle the event.
+
+**Example: Handle the `StockCountChangedEvent` defined above**
+
+````csharp
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.EventBus;
+
+namespace AbpDemo
+{
+ public class MyHandler
+ : ILocalEventHandler,
+ ITransientDependency
+ {
+ public async Task HandleEventAsync(StockCountChangedEvent eventData)
+ {
+ //TODO: your code that does somthing on the event
+ }
+ }
+}
+````
+
+That's all. `MyHandler` is **automatically discovered** by the ABP Framework and `HandleEventAsync` is called whenever a `StockCountChangedEvent` occurs. You can inject any service and perform any required logic here.
+
+* **Zero or more handlers** can subscribe to the same event.
+* A single event handler class can **subscribe to multiple events** but implementing the `ILocalEventHandler` interface for each event type.
+
+> The handler class must be registered to the dependency injection (DI). The sample above uses the `ITransientDependency` to accomplish it. See the [DI document](Dependency-Injection.md) for more options.
+
+## Transaction & Exception Behavior
+
+When an event published, subscribed event handlers are immediately executed. So;
+
+* If a handler **throws an exception**, it effects the code that published the event. That means it gets the exception on the `PublishAsync` call. So, **use try-catch yourself** in the event handler if you want to hide the error.
+* If the event publishing code is being executed inside a [Unit Of Work](Unit-Of-Work.md) scope, the event handlers also covered by the unit of work. That means if your UOW is transactional and a handler throws an exception, the transaction is rolled back.
+
+## Pre-Built Events
+
+It is very common to **publish events on entity create, update and delete** operations. ABP Framework **automatically** publish these events for all entities. You can just subscribe to the related event.
+
+**Example: Subscribe to an event that published when a user was created**
+
+````csharp
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Identity;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Domain.Entities.Events;
+using Volo.Abp.EventBus;
+
+namespace AbpDemo
+{
+ public class MyHandler
+ : ILocalEventHandler>,
+ ITransientDependency
+ {
+ public async Task HandleEventAsync(
+ EntityCreatedEventData eventData)
+ {
+ var userName = eventData.Entity.UserName;
+ var email = eventData.Entity.Email;
+ //...
+ }
+ }
+}
+````
+
+This class subscribes to the `EntityCreatedEventData`, which is published just after a user was created. You may want to send a "Welcome" email to the new user.
+
+There are two types of these events: events with past tense and events with continuous tense.
+
+### Events with Past Tense
+
+Events with past tense are published when the related unit of work completed and the entity change successfully saved to the database. If you throw an exception on these event handlers, it **can not rollback** the transaction since it was already committed.
+
+The event types are;
+
+* `EntityCreatedEventData` is published just after an entity was successfully created.
+* `EntityUpdatedEventData` is published just after an entity was successfully updated.
+* `EntityDeletedEventData` is published just after an entity was successfully deleted.
+* `EntityChangedEventData` is published just after an entity was successfully created, updated or deleted. It can be a shortcut if you need to listen any type of change - instead of subscribing to the individual events.
+
+### Events with Continuous Tense
+
+Events with continuous tense are published before completing the transaction (if database transaction is supported by the database provider being used). If you throw an exception on these event handlers, it **can rollback** the transaction since it is not completed yet and the change is not saved to the database.
+
+The event types are;
+
+* `EntityCreatingEventData` is published just before saving a new entity to the database.
+* `EntityUpdatingEventData` is published just before an existing entity is being updated.
+* `EntityDeletingEventData` is published just before an entity is being deleted.
+* `EntityChangingEventData` is published just before an entity is being created, updated or deleted. It can be a shortcut if you need to listen any type of change - instead of subscribing to the individual events.
+
+#### How It Was Implemented?
+
+Pre-build events are published when you save changes to the database;
+
+* For EF Core, they are published on `DbContext.SaveChanges`.
+* For MongoDB, they are published when you call repository's `InsertAsync`, `UpdateAsync` or `DeleteAsync` methods (since MongoDB has not a change tracking system).
\ No newline at end of file
diff --git a/docs/en/RabbitMq.md b/docs/en/RabbitMq.md
new file mode 100644
index 0000000000..11dc305b41
--- /dev/null
+++ b/docs/en/RabbitMq.md
@@ -0,0 +1,3 @@
+# RabbitMQ
+
+TODO!
\ No newline at end of file
diff --git a/docs/en/Repositories.md b/docs/en/Repositories.md
index 86a3e231c5..ff42c6f440 100644
--- a/docs/en/Repositories.md
+++ b/docs/en/Repositories.md
@@ -126,7 +126,7 @@ You can directly access the data access provider (`DbContext` in this case) to p
`IRepository` inherits from `IQueryable`, that means you can **directly use LINQ extension methods** on it, as shown in the example of the "*Generic Repositories*" section above.
-**Example: Using the `Where(...)` &and the `ToList()` extension methods**
+**Example: Using the `Where(...)` and the `ToList()` extension methods**
````csharp
var people = _personRepository
diff --git a/docs/en/UI/Angular/Permission-Management.md b/docs/en/UI/Angular/Permission-Management.md
index d86e8c96b2..ab53e35e78 100644
--- a/docs/en/UI/Angular/Permission-Management.md
+++ b/docs/en/UI/Angular/Permission-Management.md
@@ -8,7 +8,7 @@ You can get permission as boolean value from store:
```js
import { Store } from '@ngxs/store';
-import { ConfigState } from '../states';
+import { ConfigState } from '@abp/ng.core';
export class YourComponent {
constructor(private store: Store) {}
@@ -24,7 +24,7 @@ export class YourComponent {
Or you can get it via `ConfigStateService`:
```js
-import { ConfigStateService } from '../services/config-state.service';
+import { ConfigStateService } from '@abp/ng.core';
export class YourComponent {
constructor(private configStateService: ConfigStateService) {}
@@ -42,7 +42,7 @@ export class YourComponent {
You can use the `PermissionDirective` to manage visibility of a DOM Element accordingly to user's permission.
```html
-
+
This content is only visible if the user has 'AbpIdentity.Roles' permission.