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/configureawait.props b/configureawait.props index 5247c80ae0..791c3e2a57 100644 --- a/configureawait.props +++ b/configureawait.props @@ -1,8 +1,8 @@ - - - all + + + All runtime; build; native; contentfiles; analyzers diff --git a/docs/en/CLI.md b/docs/en/CLI.md index f68ac2ce2e..160bb549c3 100644 --- a/docs/en/CLI.md +++ b/docs/en/CLI.md @@ -115,6 +115,7 @@ abp update [options] * `--nuget`: Only updates NuGet packages. * `--solution-path` or `-sp`: Specify the solution path. Use the current directory by default * `--solution-name` or `-sn`: Specify the solution name. Search `*.sln` files in the directory by default. +* `--check-all`: Check the new version of each package separately. Default is `false`. ### add-package 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 c22e3c85e5..947b0f3142 100644 --- a/docs/en/Distributed-Event-Bus.md +++ b/docs/en/Distributed-Event-Bus.md @@ -179,3 +179,121 @@ That's all. 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/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/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.
``` @@ -58,6 +58,8 @@ You can use `PermissionGuard` if you want to control authenticated user's permis Add `requiredPolicy` to the `routes` property in your routing module. ```js +import { PermissionGuard } from '@abp/ng.core'; +// ... const routes: Routes = [ { path: 'path', diff --git a/docs/zh-Hans/Blob-Storing.md b/docs/zh-Hans/Blob-Storing.md index 788b104edb..43b2ebb96b 100644 --- a/docs/zh-Hans/Blob-Storing.md +++ b/docs/zh-Hans/Blob-Storing.md @@ -169,7 +169,7 @@ public class ProfileAppService : ApplicationService 如果不使用泛型参数,直接注入 `IBlobContainer` (如上所述),会得到默认容器. 注入默认容器的另一种方法是使用 `IBlobContainer`,它返回完全相同的容器. -默认容器的名称是 `Default`. +默认容器的名称是 `default`. ### 命令容器 diff --git a/docs/zh-Hans/Distributed-Event-Bus-RabbitMQ-Integration.md b/docs/zh-Hans/Distributed-Event-Bus-RabbitMQ-Integration.md new file mode 100644 index 0000000000..2a1810e309 --- /dev/null +++ b/docs/zh-Hans/Distributed-Event-Bus-RabbitMQ-Integration.md @@ -0,0 +1,134 @@ +# 分布式事件总线RabbitMQ集成 + +> 本文解释了**如何配置[RabbitMQ](https://www.rabbitmq.com/)**做为分布式总线提供程序. 参阅[分布式事件总线文档](Distributed-Event-Bus.md)了解如何使用分布式事件总线系统. + +## 安装 + +使用ABP CLI添加[Volo.Abp.EventBus.RabbitMQ[Volo.Abp.EventBus.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.EventBus.RabbitMQ)NuGet包到你的项目: + +* 安装[ABP CLI](https://docs.abp.io/en/abp/latest/CLI),如果你还没有安装. +* 在你想要安装 `Volo.Abp.EventBus.RabbitMQ` 包的 `.csproj` 文件目录打开命令行(终端). +* 运行 `abp add-package Volo.Abp.EventBus.RabbitMQ` 命令. + +如果你想要手动安装,安装[Volo.Abp.EventBus.RabbitMQ](https://www.nuget.org/packages/Volo.Abp.EventBus.RabbitMQ) NuGet 包到你的项目然后添加 `[DependsOn(typeof(AbpEventBusRabbitMqModule))]` 到你的项目[模块](Module-Development-Basics.md)类. + +## 配置 + +可以使用配置使用标准的[配置系统](Configuration.md),如 `appsettings.json` 文件,或[选项](Options.md)类. + +### `appsettings.json` 文件配置 + +这是配置RabbitMQ设置最简单的方法. 它也非常强大,因为你可以使用[由AspNet Core支持的](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/)的任何其他配置源(如环境变量). + +**示例:最小化配置与默认配置连接到本地的RabbitMQ服务器** + +````json +{ + "RabbitMQ": { + "EventBus": { + "ClientName": "MyClientName", + "ExchangeName": "MyExchangeName" + } + } +} +```` + +* `ClientName` 是应用程序的名称,用于RabbitMQ的**队列名称**. +* `ExchangeName` 是 **交换机名称**. + +参阅[RabbitMQ文档](https://www.rabbitmq.com/dotnet-api-guide.html#exchanges-and-queues)更好的了解这些选项. + +#### 连接 + +如果需要连接到本地主机以外的另一台服务器,需要配置连接属性. + +**示例: 指定主机名 (如IP地址)** + +````json +{ + "RabbitMQ": { + "Connections": { + "Default": { + "HostName": "123.123.123.123" + } + }, + "EventBus": { + "ClientName": "MyClientName", + "ExchangeName": "MyExchangeName" + } + } +} +```` + +允许定义多个连接. 在这种情况下,你可以指定用于事件总线的连接. + +**示例: 声明两个连接并将其中一个用于事件总线** + +````json +{ + "RabbitMQ": { + "Connections": { + "Default": { + "HostName": "123.123.123.123" + }, + "SecondConnection": { + "HostName": "321.321.321.321" + } + }, + "EventBus": { + "ClientName": "MyClientName", + "ExchangeName": "MyExchangeName", + "ConnectionName": "SecondConnection" + } + } +} +```` + +这允许你可以在你的应用程序使用多个RabbitMQ服务器,但将其中一个做为事件总线. + +你可以使用任何[ConnectionFactry](http://rabbitmq.github.io/rabbitmq-dotnet-client/api/RabbitMQ.Client.ConnectionFactory.html#properties)属性作为连接属性. + +**示例: 指定连接端口** + +````csharp +{ + "RabbitMQ": { + "Connections": { + "Default": { + "HostName": "123.123.123.123", + "Port": "5672" + } + } + } +} +```` + +### 选项类 + +`AbpRabbitMqOptions` 和 `AbpRabbitMqEventBusOptions` 类用于配置RabbitMQ的连接字符串和事件总线选项. + +你可以在你的[模块](Module-Development-Basics.md)的 `ConfigureServices` 方法配置选项. + +**示例: 配置连接** + +````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; +}); +```` + +**示例: 配置客户端和交换机名称** + +````csharp +Configure(options => +{ + options.ClientName = "TestApp1"; + options.ExchangeName = "TestMessages"; +}); +```` + +使用这些选项类可以与 `appsettings.json` 组合在一起. 在代码中配置选项属性会覆盖配置文件中的值. \ No newline at end of file diff --git a/docs/zh-Hans/Distributed-Event-Bus.md b/docs/zh-Hans/Distributed-Event-Bus.md new file mode 100644 index 0000000000..8416ef953d --- /dev/null +++ b/docs/zh-Hans/Distributed-Event-Bus.md @@ -0,0 +1,300 @@ +# 分布式事件总线 + +分布式事件总线系统允许**发布**和**订阅跨应用/服务边界**传输的事件. 你可以使用分布式事件总线在**微服务**或**应用程序**之间异步发送和接收消息. + +## 提供程序 + +分布式事件总线系统提供了一个可以被任何提供程序实现的**抽象**. 有两种开箱即用的提供程序: + +* `LocalDistributedEventBus` 是默认实现,实现作为进程内工作的分布式事件总线. 是的!如果没有配置真正的分布式提供程序,**默认实现的工作方式与[本地事件总线](Local-Event-Bus.md)一样**. +* `RabbitMqDistributedEventBus` 通过[RabbitMQ](https://www.rabbitmq.com/)实现分布式事件总线. 请参阅[RabbitMQ集成文档](Distributed-Event-Bus-RabbitMQ-Integration.md)了解如何配置它. + +使用本地事件总线作为默认具有一些重要的优点. 最重要的是:它允许你编写与分布式体系结构兼容的代码. 您现在可以编写一个整体应用程序,以后可以拆分成微服务. 最好通过分布式事件而不是本地事件在边界上下文之间(或在应用程序模块之间)进行通信. + +例如,[预构建的应用模块](Modules/Index.md)被设计成在分布式系统中作为服务工作,同时它们也可以在独立应用程序中作为模块工作,而不依赖于外部消息代理. + +## 发布事件 + +以下介绍了两种发布分布式事件的方法. + +### IDistributedEventBus + +可以[注入](Dependency-Injection.md) `IDistributedEventBus` 并且使用发布分布式事件. + +**示例: 产品的存货数量发生变化时发布分布式事件** + +````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` 方法需要一个参数:事件对象,它负责保持与事件相关的数据,是一个简单的普通类: + + +````csharp +using System; + +namespace AbpDemo +{ + [EventName("MyApp.Product.StockChange")] + public class StockCountChangedEto + { + public Guid ProductId { get; set; } + + public int NewCount { get; set; } + } +} +```` + +即使你不需要传输任何数据也需要创建一个类(在这种情况下为空类). + +> `Eto` 是我们按照约定使用的**E**vent **T**ransfer **O**bjects(事件传输对象)的后缀. s虽然这不是必需的,但我们发现识别这样的事件类很有用(就像应用层上的[DTO](Data-Transfer-Objects.md) 一样). + +#### 事件名称 + +`EventName`attribute是可选的,但建议使用. 如果不声明,事件名将事件名称将是事件类的全名. 这里是 `AbpDemo.StockCountChangedEto`. + +#### 关于序列化的事件对象 + +事件传输对象**必须是可序列化**的,因为将其传输到流程外时,它们将被序列化/反序列化为JSON或其他格式. + +避免循环引用,多态,私有setter,并提供默认(空)构造函数,如果你有其他的构造函数.(虽然某些序列化器可能会正常工作),就像DTO一样. + +### 实体/聚合根类 + +[实体](Entities.md)不能通过依赖注入注入服务,但是在实体/聚合根类中发布分布式事件是非常常见的. + +**示例: 在聚合根方法内发布分布式事件** + +````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` 类定义了 `AddDistributedEvent` 来添加一个新的分布式事件,事件在聚合根对象保存(创建,更新或删除)到数据库时发布. + +> 如果实体发布这样的事件,以可控的方式更改相关属性是一个好的实践,就像上面的示例一样 - `StockCount`只能由保证发布事件的 `ChangeStockCount` 方法来更改. + +#### IGeneratesDomainEvents 接口 + +实际上添加分布式事件并不是 `AggregateRoot` 类独有的. 你可以为任何实体类实现 `IGeneratesDomainEvents`. 但是 `AggregateRoot` 默认实现了它简化你的工作. + +> 不建议为不是聚合根的实体实现此接口,因为它可能不适用于此类实体的某些数据库提供程序. 例如它适用于EF Core,但不适用于MongoDB. + +#### 它是如何实现的? + +调用 `AddDistributedEvent` 不会立即发布事件. 当你将更改保存到数据库时发布该事件; + +* 对于 EF Core, 它在 `DbContext.SaveChanges` 中发布. +* 对于 MongoDB, 它在你调用仓储的 `InsertAsync`, `UpdateAsync` 或 `DeleteAsync` 方法时发由 (因为MongoDB没有更改跟踪系统). + +## 订阅事件 + +一个服务可以实现 `IDistributedEventHandler` 来处理事件. + +**示例: 处理上面定义的`StockCountChangedEto`** + +````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; + } + } +} +```` + +这就是全部. + +* `MyHandler` 由ABP框架**自动发现**,并在发生 `StockCountChangedEto` 事件时调用 `HandleEventAsync`. +* 如果你使用的是分布式消息代理,比如RabbitMQ,ABP会自动**订阅消息代理上的事件**,获取消息执行处理程序. +* 如果事件处理程序成功执行(没有抛出任何异常),它将向消息代理发送**确认(ACK)**. + +你可以在处理程序注入任何服务来执行所需的逻辑. 一个事件处理程序可以**订阅多个事件**,但是需要为每个事件实现 `IDistributedEventHandler` 接口. + +> 事件处理程序类必须注册到依赖注入(DI),示例中使用了 `ITransientDependency`. 参阅[DI文档](Dependency-Injection.md)了解更多选项. + +## 预定义的事件 + +如果你配置,ABP框架会为[实体](Entities.md)**自动发布创建,更新和删除**分布式事件. + +### 事件类型 + +有三种预定义的事件类型: + +* `EntityCreatedEto` 是实体 `T` 创建后发布. +* `EntityUpdatedEto` 是实体 `T` 更新后发布. +* `EntityDeletedEto` 是实体 `T` 删除后发布. + +这些都是泛型的, `T` 实际上是**E**vent **T**ransfer **O**bject (ETO)的类型,而不是实体的类型,因为实体对象不能做为事件数据传输,所以通常会为实体类定义一个ETO类,如为 `Product` 实体定义 `ProductEto`. + +### 订阅事件 + +订阅自动事件与订阅常规分布式事件相同. + +**示例: 产品更新后获取通知** + +````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` 实现了 `IDistributedEventHandler>`. + +### 配置 + +你可以在[模块](Module-Development-Basics.md)的 `ConfigureServices` 中配置 `AbpDistributedEntityEventOptions`添加选择器. + +**示例: 配置示例** + +````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.") + ); +}); +```` + +* 最后一个提供了灵活性来决定是否应该针对给定的实体类型发布事件. 返回 `true` 代表为该 `Type` 发布事件. + +你可以添加多个选择器. 如果选择器之一与实体类型匹配,则将其选中. + +### 事件传输对象 + +一旦你为一个实体启用了**自动事件**,ABP框架就会为实体上的更改发布事件. 如果你没有为实体指定对应的**E**vent **T**ransfer **O**bject(ETO), ABP框架会使用一个标准类型 `EntityEto`,它只有两个属性: + +* `EntityType` (`string`): 实体类的全名(包括命令空间). +* `KeysAsString` (`string`): 已更改实体的主键.如果它只有一个主键,这个属性将是主键值. 对于复合键,它包含所有用`,`(逗号)分隔的键. + +因此可以实现 `IDistributedEventHandler>` 订阅事件. 但是订阅这样的通用事件不是一个好方法,你可以为实体类型定义对应的ETO. + +**示例: 为 `Product` 声明使用 `ProductDto`** + +````csharp +Configure(options => +{ + options.AutoEventSelectors.Add(); + options.EtoMappings.Add(); +}); +```` + +在这个示例中; + +* 添加选择器允许发布 `Product` 实体的创建,更新和删除事件. +* 配置为使用 `ProductEto` 作为事件传输对象来发布与 `Product` 相关的事件. + +分布式事件系统使用[对象到对象的映射](Object-To-Object-Mapping.md)系统来映射 `Product` 对象到 `ProductEto` 对象,你需要配置映射. 请参阅可以对象到对象映射文档了解所有选项,下面的示例展示了如何使用[AutoMapper](https://automapper.org/)库配置它. + +**示例: 使用AutoMapper配置 `Product` 到 `ProductEto` 映射** + +````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; } + } +} +```` + +此示例使用AutoMapper的 `AutoMap` 属性配置的映射. 你可以创建一个配置文件类代替. 请参阅AutoMapper文档了解更多选项. \ No newline at end of file diff --git a/docs/zh-Hans/Event-Bus.md b/docs/zh-Hans/Event-Bus.md index 0adb56101d..07a623499d 100644 --- a/docs/zh-Hans/Event-Bus.md +++ b/docs/zh-Hans/Event-Bus.md @@ -1,3 +1,10 @@ -# Event Bus +# 事件总线 - TODO \ No newline at end of file +事件总线是将消息从发送方传输到接收方的中介. 它在对象,服务和应用程序之间提供了一种松散耦合的通信方式. + +## 事件总线类型 + +ABP框架提供了两种事件总线类型; + +* **[本地事件总线](Local-Event-Bus.md)** 适合进程内消息传递. +* **[分布式事件总线](Distributed-Event-Bus.md)** 适合进程间消息传递,如微服务发布和订阅分布式事件. \ No newline at end of file diff --git a/docs/zh-Hans/Local-Event-Bus.md b/docs/zh-Hans/Local-Event-Bus.md new file mode 100644 index 0000000000..b5c472734b --- /dev/null +++ b/docs/zh-Hans/Local-Event-Bus.md @@ -0,0 +1,227 @@ +# 本地事件总线 + +本地事件总线允许服务发布和订阅**进程内事件**. 这意味着如果两个服务(发布者和订阅者)在同一个进程中运行,那么它是合适的. + +## 发布事件 + +以下介绍了两种发布本地事件的方法. + +### ILocalEventBus + +可以[注入](Dependency-Injection.md) `ILocalEventBus` 并且使用发布本地事件. + +**示例: 产品的存货数量发生变化时发布本地事件** + +````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` 方法需要一个参数:事件对象,它负责保持与事件相关的数据,是一个简单的普通类: + +````csharp +using System; + +namespace AbpDemo +{ + public class StockCountChangedEvent + { + public Guid ProductId { get; set; } + + public int NewCount { get; set; } + } +} +```` + +即使你不需要传输任何数据也需要创建一个类(在这种情况下为空类). + +### 实体/聚合根类 + +[实体](Entities.md)不能通过依赖注入注入服务,但是在实体/聚合根类中发布本地事件是非常常见的. + +**示例: 在聚合根方法内发布本地事件** + +````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` 类定义了 `AddLocalEvent` 来添加一个新的本地事件,事件在聚合根对象保存(创建,更新或删除)到数据库时发布. + +> 如果实体发布这样的事件,以可控的方式更改相关属性是一个好的实践,就像上面的示例一样 - `StockCount`只能由保证发布事件的 `ChangeStockCount` 方法来更改. + +#### IGeneratesDomainEvents 接口 + +实际上添加本地事件并不是 `AggregateRoot` 类独有的. 你可以为任何实体类实现 `IGeneratesDomainEvents`. 但是 `AggregateRoot` 默认实现了它简化你的工作. + +> 不建议为不是聚合根的实体实现此接口,因为它可能不适用于此类实体的某些数据库提供程序. 例如它适用于EF Core,但不适用于MongoDB. + +#### 它是如何实现的? + +调用 `AddLocalEvent` 不会立即发布事件. 当你将更改保存到数据库时发布该事件; + +* 对于 EF Core, 它在 `DbContext.SaveChanges` 中发布. +* 对于 MongoDB, 它在你调用仓储的 `InsertAsync`, `UpdateAsync` 或 `DeleteAsync` 方法时发由 (因为MongoDB没有更改跟踪系统). + +## 订阅事件 + +一个服务可以实现 `ILocalEventHandler` 来处理事件. + +**示例: 处理上面定义的`StockCountChangedEvent`** + +````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 + } + } +} +```` + +这就是全部,`MyHandler` 由ABP框架**自动发现**,并在发生 `StockCountChangedEvent` 事件时调用 `HandleEventAsync`. + +* 事件可以由**0个或多个处理程序**订阅. +* 一个事件处理程序可以**订阅多个事件**,但是需要为每个事件实现 `ILocalEventHandler` 接口. + +> 事件处理程序类必须注册到依赖注入(DI),示例中使用了 `ITransientDependency`. 参阅[DI文档](Dependency-Injection.md)了解更多选项. + +## 事务和异常行为 + +当一个事件发布,订阅的事件处理程序将立即执行.所以; + +* 如果处理程序**抛出一个异常**,它会影响发布该事件的代码. 这意味着它在 `PublishAsync` 调用上获得异常. 因此如果你想隐藏错误,在事件处理程序中**使用try-catch**. +*如果在一个[工作单元](Unit-Of-Work.md)范围内执行的事件发布的代码,该事件处理程序也由工作单元覆盖. 这意味着,如果你的UOW是事务和处理程序抛出一个异常,事务会回滚. + +## 预定义的事件 + +**发布实体创建,更新,删除事件**是常见的操作. ABP框架为所有的实体**自动**发布这些事件. 你只需要订阅相关的事件. + +**示例: 订阅用户创建事件** + +````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; + //... + } + } +} +```` + +这个类订阅 `EntityCreatedEventData`,它在用户创建后发布. 你可能需要向新用户发送一封"欢迎"电子邮件. + +这些事件有两种类型:过去时态的事件和进行时态的事件. + +### 用过去时态事件 + +当相关工作单元完成且实体更改成功保存到数据库时,将发布带有过去时态的事件. 如果在这些事件处理程序上抛出异常,则**无法回滚**事务,因为事务已经提交. + +事件类型; + +* `EntityCreatedEventData` 当实体创建创建成功后发布. +* `EntityUpdatedEventData` 当实体创建更新成功后发布. +* `EntityDeletedEventData` 当实体创建删除成功后发布. +* `EntityChangedEventData` 当实体创建,更新,删除后发布. 如果你需要监听任何类型的更改,它是一种快捷方式 - 而不是订阅单个事件. + +### 用于进行时态事件 + +带有进行时态的事件在完成事务之前发布(如果数据库事务由所使用的数据库提供程序支持). 如果在这些事件处理程序上抛出异常,它**会回滚**事务,因为事务还没有完成,更改也没有保存到数据库中. + +事件类型; + +* `EntityCreatingEventData` 当新实体保存到数据库前发布. +* `EntityUpdatingEventData` 当已存在实体更新到数据库前发布. +* `EntityDeletingEventData` 删除实体前发布. +* `EntityChangingEventData` 当实体创建,更新,删除前发布. 如果你需要监听任何类型的更改,它是一种快捷方式 - 而不是订阅单个事件. + +#### 它是如何实现的? + +在将更改保存到数据库时发布预构建事件; + +* 对于 EF Core, 他们在 `DbContext.SaveChanges` 发布. +* 对于 MongoDB, 在你调用仓储的 `InsertAsync`, `UpdateAsync` 或 `DeleteAsync` 方法发布(因为MongoDB没有更改追踪系统). \ No newline at end of file diff --git a/docs/zh-Hans/UI/Angular/Permission-Management.md b/docs/zh-Hans/UI/Angular/Permission-Management.md index 3a50da9591..5c1ba5b4fb 100644 --- a/docs/zh-Hans/UI/Angular/Permission-Management.md +++ b/docs/zh-Hans/UI/Angular/Permission-Management.md @@ -8,7 +8,7 @@ ```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 { 或者你可以通过 `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 { 你可以使用 `PermissionDirective` 来根据用户的权限控制DOM元素是否可见. ```html -
+
仅当用户具有`AbpIdentity.Roles`权限时,此内容才可见.
``` @@ -58,6 +58,8 @@ export class YourComponent { 将 `requiredPolicy` 添加到路由模块中的 `routes`属性. ```js +import { PermissionGuard } from '@abp/ng.core'; +// ... const routes: Routes = [ { path: 'path', diff --git a/docs/zh-Hans/docs-nav.json b/docs/zh-Hans/docs-nav.json index c14355497b..04da437b7b 100644 --- a/docs/zh-Hans/docs-nav.json +++ b/docs/zh-Hans/docs-nav.json @@ -154,16 +154,23 @@ ] }, { - "text": "事件", + "text": "事件总线", "items": [ { - "text": "本地 Event Bus" + "text": "概述", + "path": "Event-Bus.md" + }, + { + "text": "本地 Event Bus", + "path": "Local-Event-Bus.md" }, { "text": "分布式 Event Bus", + "path": "Distributed-Event-Bus.md", "items": [ { - "text": "RabbitMQ 集成" + "text": "RabbitMQ 集成", + "path": "Distributed-Event-Bus-RabbitMQ-Integration.md" } ] } diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj b/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj index 544099c653..af317c263c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj @@ -19,7 +19,7 @@ - + diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Select2/Select2ScriptContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Select2/Select2ScriptContributor.cs index 1e5f138f97..81696d5e71 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Select2/Select2ScriptContributor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Select2/Select2ScriptContributor.cs @@ -12,6 +12,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Select2 { //TODO: Add select2.full.min.js or localize! context.Files.AddIfNotContains("/libs/select2/js/select2.min.js"); + context.Files.AddIfNotContains("/libs/select2/js/select2-bootstrap-modal-patch.js"); } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj index d14d639fbb..99a9357392 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj index 90500a456b..47899625d4 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj @@ -26,9 +26,9 @@ - - - + + + diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Authentication/ChallengeAccountController.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Authentication/ChallengeAccountController.cs index 15854e10a6..781866232b 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Authentication/ChallengeAccountController.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Authentication/ChallengeAccountController.cs @@ -52,6 +52,21 @@ namespace Volo.Abp.AspNetCore.Mvc.Authentication return new SignOutResult(ChallengeAuthenticationSchemas); } + [HttpGet] + public async Task FrontChannelLogout(string sid) + { + if (User.Identity.IsAuthenticated) + { + var currentSid = User.FindFirst("sid").Value ?? string.Empty; + if (string.Equals(currentSid, sid, StringComparison.Ordinal)) + { + await Logout(); + } + } + + return NoContent(); + } + protected RedirectResult RedirectSafely(string returnUrl, string returnUrlHash = null) { return Redirect(GetRedirectUrl(returnUrl, returnUrlHash)); diff --git a/framework/src/Volo.Abp.AspNetCore.Serilog/Volo.Abp.AspNetCore.Serilog.csproj b/framework/src/Volo.Abp.AspNetCore.Serilog/Volo.Abp.AspNetCore.Serilog.csproj index b0bb8930df..348aeb0342 100644 --- a/framework/src/Volo.Abp.AspNetCore.Serilog/Volo.Abp.AspNetCore.Serilog.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Serilog/Volo.Abp.AspNetCore.Serilog.csproj @@ -22,7 +22,7 @@ - + diff --git a/framework/src/Volo.Abp.AspNetCore.TestBase/Volo.Abp.AspNetCore.TestBase.csproj b/framework/src/Volo.Abp.AspNetCore.TestBase/Volo.Abp.AspNetCore.TestBase.csproj index 2ff1d539a6..a4dcd1c8c5 100644 --- a/framework/src/Volo.Abp.AspNetCore.TestBase/Volo.Abp.AspNetCore.TestBase.csproj +++ b/framework/src/Volo.Abp.AspNetCore.TestBase/Volo.Abp.AspNetCore.TestBase.csproj @@ -24,7 +24,7 @@ - + diff --git a/framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj b/framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj index e5183688df..b8ff62572b 100644 --- a/framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj +++ b/framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj b/framework/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj index 45cc6e2d94..3c5c275117 100644 --- a/framework/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj +++ b/framework/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj @@ -15,9 +15,9 @@ - - - + + + diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo.Abp.BlobStoring.Azure.csproj b/framework/src/Volo.Abp.BlobStoring.Azure/Volo.Abp.BlobStoring.Azure.csproj index 1e7c51f4fc..6434e1d43c 100644 --- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo.Abp.BlobStoring.Azure.csproj +++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo.Abp.BlobStoring.Azure.csproj @@ -16,7 +16,7 @@ - + diff --git a/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo.Abp.BlobStoring.FileSystem.csproj b/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo.Abp.BlobStoring.FileSystem.csproj index 88fc08e34e..65242db157 100644 --- a/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo.Abp.BlobStoring.FileSystem.csproj +++ b/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo.Abp.BlobStoring.FileSystem.csproj @@ -16,7 +16,7 @@ - + diff --git a/framework/src/Volo.Abp.Caching/Volo.Abp.Caching.csproj b/framework/src/Volo.Abp.Caching/Volo.Abp.Caching.csproj index db744f410e..5ee096a493 100644 --- a/framework/src/Volo.Abp.Caching/Volo.Abp.Caching.csproj +++ b/framework/src/Volo.Abp.Caching/Volo.Abp.Caching.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.Castle.Core/Volo.Abp.Castle.Core.csproj b/framework/src/Volo.Abp.Castle.Core/Volo.Abp.Castle.Core.csproj index 24f7fbe682..7e742c0467 100644 --- a/framework/src/Volo.Abp.Castle.Core/Volo.Abp.Castle.Core.csproj +++ b/framework/src/Volo.Abp.Castle.Core/Volo.Abp.Castle.Core.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj b/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj index 0b9306be91..40eecfd06a 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj +++ b/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj @@ -16,11 +16,11 @@ - - + + - - + + diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs index ca8bfa9bf8..5fe255828e 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs @@ -63,11 +63,13 @@ namespace Volo.Abp.Cli.Commands solution = Directory.GetFiles(directory, "*.sln", SearchOption.AllDirectories).FirstOrDefault(); } + var checkAll = commandLineArgs.Options.ContainsKey(Options.CheckAll.Long); + if (solution != null) { var solutionName = Path.GetFileName(solution).RemovePostFix(".sln"); - await _nugetPackagesVersionUpdater.UpdateSolutionAsync(solution, includePreviews); + await _nugetPackagesVersionUpdater.UpdateSolutionAsync(solution, includePreviews, checkAll: checkAll); Logger.LogInformation($"Volo packages are updated in {solutionName} solution."); return; @@ -79,7 +81,7 @@ namespace Volo.Abp.Cli.Commands { var projectName = Path.GetFileName(project).RemovePostFix(".csproj"); - await _nugetPackagesVersionUpdater.UpdateProjectAsync(project, includePreviews); + await _nugetPackagesVersionUpdater.UpdateProjectAsync(project, includePreviews, checkAll: checkAll); Logger.LogInformation($"Volo packages are updated in {projectName} project."); return; @@ -107,6 +109,7 @@ namespace Volo.Abp.Cli.Commands sb.AppendLine("--nuget (Only updates Nuget packages)"); sb.AppendLine("-sp|--solution-path (Specify the solution path)"); sb.AppendLine("-sn|--solution-name (Specify the solution name)"); + sb.AppendLine("--check-all (Check the new version of each package separately)"); sb.AppendLine(""); sb.AppendLine("Some examples:"); sb.AppendLine(""); @@ -149,6 +152,11 @@ namespace Volo.Abp.Cli.Commands public const string Npm = "npm"; public const string NuGet = "nuget"; } + + public static class CheckAll + { + public const string Long = "check-all"; + } } } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs index 1a279fafc7..02ae0040bc 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; @@ -52,34 +53,38 @@ namespace Volo.Abp.Cli.ProjectModification _npmGlobalPackagesChecker.Check(); - foreach (var file in fileList) + var packagesUpdated = new ConcurrentDictionary(); + async Task UpdateAsync(string file) { - var packagesUpdated = await UpdatePackagesInFile(file, includePreviews, switchToStable); + var updated = await UpdatePackagesInFile(file, includePreviews, switchToStable); + packagesUpdated.TryAdd(file, updated); + }; - if (packagesUpdated) - { - var fileDirectory = Path.GetDirectoryName(file).EnsureEndsWith(Path.DirectorySeparatorChar); + Task.WaitAll(fileList.Select(UpdateAsync).ToArray()); + + foreach (var file in packagesUpdated.Where(x => x.Value)) + { + var fileDirectory = Path.GetDirectoryName(file.Key).EnsureEndsWith(Path.DirectorySeparatorChar); - if (IsAngularProject(fileDirectory)) + if (IsAngularProject(fileDirectory)) + { + if (includePreviews) { - if (includePreviews) - { - await CreateNpmrcFileAsync(Path.GetDirectoryName(file)); - } - else if (switchToStable) - { - await DeleteNpmrcFileAsync(Path.GetDirectoryName(file)); - } + await CreateNpmrcFileAsync(Path.GetDirectoryName(file.Key)); } - - RunYarn(fileDirectory); - - if (!IsAngularProject(fileDirectory)) + else if (switchToStable) { - Thread.Sleep(500); - RunGulp(fileDirectory); + await DeleteNpmrcFileAsync(Path.GetDirectoryName(file.Key)); } } + + RunYarn(fileDirectory); + + if (!IsAngularProject(fileDirectory)) + { + Thread.Sleep(500); + RunGulp(fileDirectory); + } } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs index fb2a386ef9..9661dceddd 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Collections.Generic; using NuGet.Versioning; using System.IO; using System.Linq; @@ -24,19 +25,47 @@ namespace Volo.Abp.Cli.ProjectModification Logger = NullLogger.Instance; } - public async Task UpdateSolutionAsync(string solutionPath, bool includePreviews = false, bool switchToStable = false) + public async Task UpdateSolutionAsync(string solutionPath, bool includePreviews = false, bool switchToStable = false, bool checkAll = false) { var projectPaths = ProjectFinder.GetProjectFiles(solutionPath); - foreach (var filePath in projectPaths) + if (checkAll) { - await UpdateInternalAsync(filePath, includePreviews, switchToStable); + Task.WaitAll(projectPaths.Select(projectPath => UpdateInternalAsync(projectPath, includePreviews, switchToStable)).ToArray()); + } + else + { + var latestVersionFromNuget = await _nuGetService.GetLatestVersionOrNullAsync("Volo.Abp.Core"); + var latestVersionFromMyGet = await GetLatestVersionFromMyGet("Volo.Abp.Core"); + + async Task UpdateAsync(string filePath) + { + var fileContent = File.ReadAllText(filePath); + var updatedContent = await UpdateVoloPackagesAsync(fileContent, includePreviews, switchToStable, latestVersionFromNuget, latestVersionFromMyGet); + + File.WriteAllText(filePath, updatedContent); + } + + Task.WaitAll(projectPaths.Select(UpdateAsync).ToArray()); } } - public async Task UpdateProjectAsync(string projectPath, bool includePreviews = false, bool switchToStable = false) + public async Task UpdateProjectAsync(string projectPath, bool includePreviews = false, bool switchToStable = false, bool checkAll = false) { - await UpdateInternalAsync(projectPath, includePreviews, switchToStable); + if (checkAll) + { + await UpdateInternalAsync(projectPath, includePreviews, switchToStable); + } + else + { + var latestVersionFromNuget = await _nuGetService.GetLatestVersionOrNullAsync("Volo.Abp.Core"); + var latestVersionFromMyGet = await GetLatestVersionFromMyGet("Volo.Abp.Core"); + + var fileContent = File.ReadAllText(projectPath); + var updatedContent = await UpdateVoloPackagesAsync(fileContent, includePreviews, switchToStable, latestVersionFromNuget, latestVersionFromMyGet); + + File.WriteAllText(projectPath, updatedContent); + } } protected virtual async Task UpdateInternalAsync(string projectPath, bool includePreviews = false, bool switchToStable = false) @@ -47,7 +76,7 @@ namespace Volo.Abp.Cli.ProjectModification File.WriteAllText(projectPath, updatedContent); } - private async Task UpdateVoloPackagesAsync(string content, bool includePreviews = false, bool switchToStable = false) + private async Task UpdateVoloPackagesAsync(string content, bool includePreviews = false, bool switchToStable = false, SemanticVersion latestNugetVersion = null, string latestMyGetVersion = null) { string packageId = null; @@ -81,7 +110,7 @@ namespace Volo.Abp.Cli.ProjectModification if (includePreviews || (currentVersion.Contains("-preview") && !switchToStable)) { - var latestVersion = await GetLatestVersionFromMyGet(packageId); + var latestVersion = latestMyGetVersion ?? await GetLatestVersionFromMyGet(packageId); if (currentVersion != latestVersion) { @@ -95,7 +124,7 @@ namespace Volo.Abp.Cli.ProjectModification } else { - var latestVersion = await _nuGetService.GetLatestVersionOrNullAsync(packageId); + var latestVersion = latestNugetVersion ?? await _nuGetService.GetLatestVersionOrNullAsync(packageId); if (latestVersion != null && (currentVersion.Contains("-preview") || currentSemanticVersion < latestVersion)) { @@ -109,7 +138,7 @@ namespace Volo.Abp.Cli.ProjectModification } } - return await Task.FromResult(doc.OuterXml); + return doc.OuterXml; } } catch (Exception ex) diff --git a/framework/src/Volo.Abp.Cli/Volo.Abp.Cli.csproj b/framework/src/Volo.Abp.Cli/Volo.Abp.Cli.csproj index aec34db41a..424e09b115 100644 --- a/framework/src/Volo.Abp.Cli/Volo.Abp.Cli.csproj +++ b/framework/src/Volo.Abp.Cli/Volo.Abp.Cli.csproj @@ -18,8 +18,8 @@ - - + + diff --git a/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj b/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj index 50fb328387..000433c83d 100644 --- a/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj +++ b/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj @@ -15,20 +15,20 @@ - - - - - - - - - - + + + + + + + + + + - + - + diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeHelper.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeHelper.cs index 83182fc965..83c2c4c38e 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeHelper.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeHelper.cs @@ -359,5 +359,15 @@ namespace Volo.Abp.Reflection ? type.GenericTypeArguments[0] : type; } + + public static bool IsDefaultValue([CanBeNull] object obj) + { + if (obj == null) + { + return true; + } + + return obj.Equals(GetDefaultValue(obj.GetType())); + } } } diff --git a/framework/src/Volo.Abp.Dapper/Volo.Abp.Dapper.csproj b/framework/src/Volo.Abp.Dapper/Volo.Abp.Dapper.csproj index 27a92976e5..4feb946600 100644 --- a/framework/src/Volo.Abp.Dapper/Volo.Abp.Dapper.csproj +++ b/framework/src/Volo.Abp.Dapper/Volo.Abp.Dapper.csproj @@ -19,7 +19,7 @@ - + diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs index b78a5aa400..cf1b643305 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Entity.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Reflection; -using Volo.Abp.MultiTenancy; namespace Volo.Abp.Domain.Entities { @@ -16,6 +14,11 @@ namespace Volo.Abp.Domain.Entities } public abstract object[] GetKeys(); + + public bool EntityEquals(IEntity other) + { + return EntityHelper.EntityEquals(this, other); + } } /// @@ -35,44 +38,6 @@ namespace Volo.Abp.Domain.Entities Id = id; } - public bool EntityEquals(object obj) - { - if (obj == null || !(obj is Entity)) - { - return false; - } - - //Same instances must be considered as equal - if (ReferenceEquals(this, obj)) - { - return true; - } - - //Transient objects are not considered as equal - var other = (Entity)obj; - if (EntityHelper.HasDefaultId(this) && EntityHelper.HasDefaultId(other)) - { - return false; - } - - //Must have a IS-A relation of types or must be same type - var typeOfThis = GetType().GetTypeInfo(); - var typeOfOther = other.GetType().GetTypeInfo(); - if (!typeOfThis.IsAssignableFrom(typeOfOther) && !typeOfOther.IsAssignableFrom(typeOfThis)) - { - return false; - } - - //Different tenants may have an entity with same Id. - if (this is IMultiTenant && other is IMultiTenant && - this.As().TenantId != other.As().TenantId) - { - return false; - } - - return Id.Equals(other.Id); - } - public override object[] GetKeys() { return new object[] {Id}; diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs index ad082c3fb0..65f2992257 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/EntityHelper.cs @@ -5,6 +5,8 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; using JetBrains.Annotations; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Reflection; namespace Volo.Abp.Domain.Entities { @@ -16,6 +18,98 @@ namespace Volo.Abp.Domain.Entities private static readonly ConcurrentDictionary CachedIdProperties = new ConcurrentDictionary(); + public static bool EntityEquals(IEntity entity1, IEntity entity2) + { + if (entity1 == null || entity2 == null) + { + return false; + } + + //Same instances must be considered as equal + if (ReferenceEquals(entity1, entity2)) + { + return true; + } + + //Must have a IS-A relation of types or must be same type + var typeOfEntity1 = entity1.GetType(); + var typeOfEntity2 = entity2.GetType(); + if (!typeOfEntity1.IsAssignableFrom(typeOfEntity2) && !typeOfEntity2.IsAssignableFrom(typeOfEntity1)) + { + return false; + } + + //Different tenants may have an entity with same Id. + if (entity1 is IMultiTenant && entity2 is IMultiTenant) + { + var tenant1Id = ((IMultiTenant) entity1).TenantId; + var tenant2Id = ((IMultiTenant) entity2).TenantId; + + if (tenant1Id != tenant2Id) + { + if (tenant1Id == null || tenant2Id == null) + { + return false; + } + + if (!tenant1Id.Equals(tenant2Id)) + { + return false; + } + } + } + + //Transient objects are not considered as equal + if (HasDefaultKeys(entity1) && HasDefaultKeys(entity2)) + { + return false; + } + + var entity1Keys = entity1.GetKeys(); + var entity2Keys = entity2.GetKeys(); + + if (entity1Keys.Length != entity2Keys.Length) + { + return false; + } + + for (var i = 0; i < entity1Keys.Length; i++) + { + var entity1Key = entity1Keys[i]; + var entity2Key = entity2Keys[i]; + + if (entity1Key == null) + { + if (entity2Key == null) + { + //Both null, so considered as equals + continue; + } + + //entity2Key is not null! + return false; + } + + if (entity2Key == null) + { + //entity1Key was not null! + return false; + } + + if (TypeHelper.IsDefaultValue(entity1Key) && TypeHelper.IsDefaultValue(entity2Key)) + { + return false; + } + + if (!entity1Key.Equals(entity2Key)) + { + return false; + } + } + + return true; + } + public static bool IsEntity([NotNull] Type type) { return typeof(IEntity).IsAssignableFrom(type); @@ -25,7 +119,8 @@ namespace Volo.Abp.Domain.Entities { foreach (var interfaceType in type.GetInterfaces()) { - if (interfaceType.GetTypeInfo().IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IEntity<>)) + if (interfaceType.GetTypeInfo().IsGenericType && + interfaceType.GetGenericTypeDefinition() == typeof(IEntity<>)) { return true; } @@ -55,6 +150,44 @@ namespace Volo.Abp.Domain.Entities return false; } + private static bool IsDefaultKeyValue(object value) + { + if (value == null) + { + return true; + } + + var type = value.GetType(); + + //Workaround for EF Core since it sets int/long to min value when attaching to DbContext + if (type == typeof(int)) + { + return Convert.ToInt32(value) <= 0; + } + + if (type == typeof(long)) + { + return Convert.ToInt64(value) <= 0; + } + + return TypeHelper.IsDefaultValue(value); + } + + public static bool HasDefaultKeys([NotNull] IEntity entity) + { + Check.NotNull(entity, nameof(entity)); + + foreach (var key in entity.GetKeys()) + { + if (!IsDefaultKeyValue(key)) + { + return false; + } + } + + return true; + } + /// /// Tries to find the primary key type of the given entity type. /// May return null if given type does not implement @@ -75,12 +208,14 @@ namespace Volo.Abp.Domain.Entities { if (!typeof(IEntity).IsAssignableFrom(entityType)) { - throw new AbpException($"Given {nameof(entityType)} is not an entity. It should implement {typeof(IEntity).AssemblyQualifiedName}!"); + throw new AbpException( + $"Given {nameof(entityType)} is not an entity. It should implement {typeof(IEntity).AssemblyQualifiedName}!"); } foreach (var interfaceType in entityType.GetTypeInfo().GetInterfaces()) { - if (interfaceType.GetTypeInfo().IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IEntity<>)) + if (interfaceType.GetTypeInfo().IsGenericType && + interfaceType.GetGenericTypeDefinition() == typeof(IEntity<>)) { return interfaceType.GenericTypeArguments[0]; } @@ -132,4 +267,4 @@ namespace Volo.Abp.Domain.Entities property?.SetValue(entity, idFactory()); } } -} +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorList.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorList.cs index f705f892d5..328c74e324 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorList.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorList.cs @@ -4,9 +4,6 @@ namespace Volo.Abp.Domain.Entities.Events.Distributed { public class AutoEntityDistributedEventSelectorList : List, IAutoEntityDistributedEventSelectorList { - public bool RemoveByName(string name) - { - return RemoveAll(s => s.Name == name) > 0; - } + } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorListExtensions.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorListExtensions.cs index e078dfaf43..d2a0622f54 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorListExtensions.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorListExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; @@ -69,6 +70,44 @@ namespace Volo.Abp.Domain.Entities.Events.Distributed ); } + public static void Add( + [NotNull] this IAutoEntityDistributedEventSelectorList selectors, + string selectorName, + Func predicate) + { + Check.NotNull(selectors, nameof(selectors)); + + if (selectors.Any(s => s.Name == selectorName)) + { + throw new AbpException($"There is already a selector added before with the same name: {selectorName}"); + } + + selectors.Add( + new NamedTypeSelector( + selectorName, + predicate + ) + ); + } + + public static void Add( + [NotNull] this IAutoEntityDistributedEventSelectorList selectors, + Func predicate) + { + selectors.Add(Guid.NewGuid().ToString("N"), predicate); + } + + public static bool RemoveByName( + [NotNull] this IAutoEntityDistributedEventSelectorList selectors, + [NotNull] string name) + { + Check.NotNull(selectors, nameof(selectors)); + Check.NotNull(name, nameof(name)); + + return selectors.RemoveAll(s => s.Name == name).Count > 0; + } + + public static bool IsMatch([NotNull] this IAutoEntityDistributedEventSelectorList selectors, Type entityType) { Check.NotNull(selectors, nameof(selectors)); diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/IAutoEntityDistributedEventSelectorList.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/IAutoEntityDistributedEventSelectorList.cs index 589942e60e..fc130eb55c 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/IAutoEntityDistributedEventSelectorList.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/Distributed/IAutoEntityDistributedEventSelectorList.cs @@ -1,9 +1,9 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; namespace Volo.Abp.Domain.Entities.Events.Distributed { public interface IAutoEntityDistributedEventSelectorList : IList { - bool RemoveByName(string name); } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs index cad12b1450..5de3b22c77 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Volo.Abp.Auditing; using Volo.Abp.DependencyInjection; @@ -18,6 +21,7 @@ namespace Volo.Abp.Domain.Entities.Events /// public class EntityChangeEventHelper : IEntityChangeEventHelper, ITransientDependency { + public ILogger Logger { get; set; } public ILocalEventBus LocalEventBus { get; set; } public IDistributedEventBus DistributedEventBus { get; set; } @@ -36,6 +40,7 @@ namespace Volo.Abp.Domain.Entities.Events LocalEventBus = NullLocalEventBus.Instance; DistributedEventBus = NullDistributedEventBus.Instance; + Logger = NullLogger.Instance; } public async Task TriggerEventsAsync(EntityChangeReport changeReport) @@ -56,6 +61,7 @@ namespace Volo.Abp.Domain.Entities.Events LocalEventBus, typeof(EntityCreatingEventData<>), entity, + entity, true ); } @@ -66,6 +72,7 @@ namespace Volo.Abp.Domain.Entities.Events LocalEventBus, typeof(EntityCreatedEventData<>), entity, + entity, false ); @@ -78,6 +85,7 @@ namespace Volo.Abp.Domain.Entities.Events DistributedEventBus, typeof(EntityCreatedEto<>), eto, + entity, false ); } @@ -101,6 +109,7 @@ namespace Volo.Abp.Domain.Entities.Events LocalEventBus, typeof(EntityUpdatingEventData<>), entity, + entity, true ); } @@ -111,6 +120,7 @@ namespace Volo.Abp.Domain.Entities.Events LocalEventBus, typeof(EntityUpdatedEventData<>), entity, + entity, false ); @@ -123,6 +133,7 @@ namespace Volo.Abp.Domain.Entities.Events DistributedEventBus, typeof(EntityUpdatedEto<>), eto, + entity, false ); } @@ -135,6 +146,7 @@ namespace Volo.Abp.Domain.Entities.Events LocalEventBus, typeof(EntityDeletingEventData<>), entity, + entity, true ); } @@ -145,6 +157,7 @@ namespace Volo.Abp.Domain.Entities.Events LocalEventBus, typeof(EntityDeletedEventData<>), entity, + entity, false ); @@ -157,6 +170,7 @@ namespace Volo.Abp.Domain.Entities.Events DistributedEventBus, typeof(EntityDeletedEto<>), eto, + entity, false ); } @@ -206,22 +220,129 @@ namespace Volo.Abp.Domain.Entities.Events { foreach (var distributedEvent in distributedEvents) { - await DistributedEventBus.PublishAsync(distributedEvent.EventData.GetType(), distributedEvent.EventData); + await DistributedEventBus.PublishAsync(distributedEvent.EventData.GetType(), + distributedEvent.EventData); } } - protected virtual async Task TriggerEventWithEntity(IEventBus eventPublisher, Type genericEventType, object entity, bool triggerInCurrentUnitOfWork) + protected virtual async Task TriggerEventWithEntity( + IEventBus eventPublisher, + Type genericEventType, + object entityOrEto, + object originalEntity, + bool triggerInCurrentUnitOfWork) { - var entityType = ProxyHelper.UnProxy(entity).GetType(); + var entityType = ProxyHelper.UnProxy(entityOrEto).GetType(); var eventType = genericEventType.MakeGenericType(entityType); + var currentUow = UnitOfWorkManager.Current; - if (triggerInCurrentUnitOfWork || UnitOfWorkManager.Current == null) + if (triggerInCurrentUnitOfWork || currentUow == null) { - await eventPublisher.PublishAsync(eventType, Activator.CreateInstance(eventType, entity)); + await eventPublisher.PublishAsync( + eventType, + Activator.CreateInstance(eventType, entityOrEto) + ); + return; } - UnitOfWorkManager.Current.OnCompleted(() => eventPublisher.PublishAsync(eventType, Activator.CreateInstance(eventType, entity))); + var eventList = GetEventList(currentUow); + var isFirstEvent = !eventList.Any(); + + eventList.AddUniqueEvent(eventPublisher, eventType, entityOrEto, originalEntity); + + /* Register to OnCompleted if this is the first item. + * Other items will already be in the list once the UOW completes. + */ + if (isFirstEvent) + { + currentUow.OnCompleted( + async () => + { + foreach (var eventEntry in eventList) + { + try + { + await eventPublisher.PublishAsync( + eventEntry.EventType, + Activator.CreateInstance(eventEntry.EventType, eventEntry.EntityOrEto) + ); + } + catch (Exception ex) + { + Logger.LogError( + $"Caught an exception while publishing the event '{eventType.FullName}' for the entity '{entityOrEto}'"); + Logger.LogException(ex); + } + } + } + ); + } + } + + private EntityChangeEventList GetEventList(IUnitOfWork currentUow) + { + return (EntityChangeEventList) currentUow.Items.GetOrAdd( + "AbpEntityChangeEventList", + () => new EntityChangeEventList() + ); + } + + private class EntityChangeEventList : List + { + public void AddUniqueEvent(IEventBus eventBus, Type eventType, object entityOrEto, object originalEntity) + { + var newEntry = new EntityChangeEventEntry(eventBus, eventType, entityOrEto, originalEntity); + + //Latest "same" event overrides the previous events. + for (var i = 0; i < Count; i++) + { + if (this[i].IsSameEvent(newEntry)) + { + this[i] = newEntry; + return; + } + } + + //If this is a "new" event, add to the end + Add(newEntry); + } + } + + private class EntityChangeEventEntry + { + public IEventBus EventBus { get; } + + public Type EventType { get; } + + public object EntityOrEto { get; } + + public object OriginalEntity { get; } + + public EntityChangeEventEntry(IEventBus eventBus, Type eventType, object entityOrEto, object originalEntity) + { + EventType = eventType; + EntityOrEto = entityOrEto; + OriginalEntity = originalEntity; + EventBus = eventBus; + } + + public bool IsSameEvent(EntityChangeEventEntry otherEntry) + { + if (EventBus != otherEntry.EventBus || EventType != otherEntry.EventType) + { + return false; + } + + var originalEntityRef = OriginalEntity as IEntity; + var otherOriginalEntityRef = otherEntry.OriginalEntity as IEntity; + if (originalEntityRef == null || otherOriginalEntityRef == null) + { + return false; + } + + return EntityHelper.EntityEquals(originalEntityRef, otherOriginalEntityRef); + } } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.Oracle.Devart/Volo.Abp.EntityFrameworkCore.Oracle.Devart.csproj b/framework/src/Volo.Abp.EntityFrameworkCore.Oracle.Devart/Volo.Abp.EntityFrameworkCore.Oracle.Devart.csproj index c4763c96ca..8043a1ff8e 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore.Oracle.Devart/Volo.Abp.EntityFrameworkCore.Oracle.Devart.csproj +++ b/framework/src/Volo.Abp.EntityFrameworkCore.Oracle.Devart/Volo.Abp.EntityFrameworkCore.Oracle.Devart.csproj @@ -19,7 +19,7 @@ - + diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo.Abp.EntityFrameworkCore.PostgreSql.csproj b/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo.Abp.EntityFrameworkCore.PostgreSql.csproj index ced9c624ad..96de9fdd1c 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo.Abp.EntityFrameworkCore.PostgreSql.csproj +++ b/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo.Abp.EntityFrameworkCore.PostgreSql.csproj @@ -19,7 +19,7 @@ - + diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.SqlServer/Volo.Abp.EntityFrameworkCore.SqlServer.csproj b/framework/src/Volo.Abp.EntityFrameworkCore.SqlServer/Volo.Abp.EntityFrameworkCore.SqlServer.csproj index 309e53274f..988c3688ee 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore.SqlServer/Volo.Abp.EntityFrameworkCore.SqlServer.csproj +++ b/framework/src/Volo.Abp.EntityFrameworkCore.SqlServer/Volo.Abp.EntityFrameworkCore.SqlServer.csproj @@ -19,7 +19,7 @@ - + diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.Sqlite/Volo.Abp.EntityFrameworkCore.Sqlite.csproj b/framework/src/Volo.Abp.EntityFrameworkCore.Sqlite/Volo.Abp.EntityFrameworkCore.Sqlite.csproj index 9f4f26c45b..ce5c9a1716 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore.Sqlite/Volo.Abp.EntityFrameworkCore.Sqlite.csproj +++ b/framework/src/Volo.Abp.EntityFrameworkCore.Sqlite/Volo.Abp.EntityFrameworkCore.Sqlite.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo.Abp.EntityFrameworkCore.csproj b/framework/src/Volo.Abp.EntityFrameworkCore/Volo.Abp.EntityFrameworkCore.csproj index 3ce20b3f4e..da97fb5977 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo.Abp.EntityFrameworkCore.csproj +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo.Abp.EntityFrameworkCore.csproj @@ -20,8 +20,8 @@ - - + + diff --git a/framework/src/Volo.Abp.FluentValidation/Volo.Abp.FluentValidation.csproj b/framework/src/Volo.Abp.FluentValidation/Volo.Abp.FluentValidation.csproj index 52cee1ade7..68ce50ec9d 100644 --- a/framework/src/Volo.Abp.FluentValidation/Volo.Abp.FluentValidation.csproj +++ b/framework/src/Volo.Abp.FluentValidation/Volo.Abp.FluentValidation.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.Http.Client/Volo.Abp.Http.Client.csproj b/framework/src/Volo.Abp.Http.Client/Volo.Abp.Http.Client.csproj index 8607f32a35..4441e0bc17 100644 --- a/framework/src/Volo.Abp.Http.Client/Volo.Abp.Http.Client.csproj +++ b/framework/src/Volo.Abp.Http.Client/Volo.Abp.Http.Client.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.IdentityModel/Volo.Abp.IdentityModel.csproj b/framework/src/Volo.Abp.IdentityModel/Volo.Abp.IdentityModel.csproj index 6c19f18397..0143db8265 100644 --- a/framework/src/Volo.Abp.IdentityModel/Volo.Abp.IdentityModel.csproj +++ b/framework/src/Volo.Abp.IdentityModel/Volo.Abp.IdentityModel.csproj @@ -15,8 +15,8 @@ - - + + diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/tr.json b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/tr.json new file mode 100644 index 0000000000..4eb4a1209b --- /dev/null +++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/tr.json @@ -0,0 +1,7 @@ +{ + "culture": "tr", + "texts": { + "DisplayName:Abp.Localization.DefaultLanguage": "Varsayılan dil", + "Description:Abp.Localization.DefaultLanguage": "Varsayılan uygulama dili." + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.MailKit/Volo.Abp.MailKit.csproj b/framework/src/Volo.Abp.MailKit/Volo.Abp.MailKit.csproj index 3f75ccba80..ddded71dce 100644 --- a/framework/src/Volo.Abp.MailKit/Volo.Abp.MailKit.csproj +++ b/framework/src/Volo.Abp.MailKit/Volo.Abp.MailKit.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.Minify/Volo.Abp.Minify.csproj b/framework/src/Volo.Abp.Minify/Volo.Abp.Minify.csproj index ee2ecc23e6..1b2f266637 100644 --- a/framework/src/Volo.Abp.Minify/Volo.Abp.Minify.csproj +++ b/framework/src/Volo.Abp.Minify/Volo.Abp.Minify.csproj @@ -19,7 +19,7 @@ - + diff --git a/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj b/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj index 7e14eb9a9e..2b9e46f43d 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj +++ b/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj b/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj index 7bcc0400b5..41bba98866 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj +++ b/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hant.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hant.json index ae50048d03..496e6e3e9d 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hant.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hant.json @@ -13,18 +13,22 @@ "DefaultErrorMessage404": "未找到資源!", "DefaultErrorMessage404Detail": "未在服務中找到請求的資源!", "EntityNotFoundErrorMessage": "實體 {0} 不存在,id = {1}!", + "Languages": "語系", "Error": "錯誤", "AreYouSure": "你確定嗎?", "Cancel": "取消", "Yes": "是", "No": "否", + "Ok": "好", "Close": "關閉", "Save": "保存", "SavingWithThreeDot": "保存中...", "Actions": "操作", "Delete": "刪除", "Edit": "修改", - "Refresh": "刷新", + "Refresh": "更新", + "Language": "語言", + "LoadMore": "讀更多", "ProcessingWithThreeDot": "處理中...", "LoadingWithThreeDot": "載入中...", "Welcome": "歡迎", @@ -43,11 +47,13 @@ "PagerInfoEmpty": "顯示0個紀錄中的0到0", "PagerInfoFiltered": "(從 _MAX_ 所有紀錄中過濾掉)", "NoDataAvailableInDatatable": "資料表中沒有資料", + "Total": "總共", + "Selected": "已選擇", "PagerShowMenuEntries": "顯示 _MENU_ 實體", "DatatableActionDropdownDefaultText": "操作", "ChangePassword": "修改密碼", "PersonalInfo": "個人資料", - "AreYouSureYouWantToCancelEditingWarningMessage": "你有未保存的更改.", + "AreYouSureYouWantToCancelEditingWarningMessage": "你有未保存的更改", "UnhandledException": "未處理的異常!", "401Message": "未授權", "403Message": "禁止訪問", @@ -55,6 +61,6 @@ "500Message": "內部伺服器錯誤", "GoHomePage": "返回首頁", "GoBack": "返回", - "Search": "搜索" + "Search": "查詢" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.VirtualFileSystem/Volo.Abp.VirtualFileSystem.csproj b/framework/src/Volo.Abp.VirtualFileSystem/Volo.Abp.VirtualFileSystem.csproj index 46995e4eb4..f3a0fefb2a 100644 --- a/framework/src/Volo.Abp.VirtualFileSystem/Volo.Abp.VirtualFileSystem.csproj +++ b/framework/src/Volo.Abp.VirtualFileSystem/Volo.Abp.VirtualFileSystem.csproj @@ -15,8 +15,8 @@ - - + + diff --git a/framework/test/AbpTestBase/AbpTestBase.csproj b/framework/test/AbpTestBase/AbpTestBase.csproj index e1a625580d..a1b2dcd89b 100644 --- a/framework/test/AbpTestBase/AbpTestBase.csproj +++ b/framework/test/AbpTestBase/AbpTestBase.csproj @@ -14,12 +14,12 @@ - - + + - + diff --git a/framework/test/SimpleConsoleDemo/SimpleConsoleDemo.csproj b/framework/test/SimpleConsoleDemo/SimpleConsoleDemo.csproj index 6cd2465068..49c80c56db 100644 --- a/framework/test/SimpleConsoleDemo/SimpleConsoleDemo.csproj +++ b/framework/test/SimpleConsoleDemo/SimpleConsoleDemo.csproj @@ -18,7 +18,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.Authentication.OAuth.Tests/Volo.Abp.AspNetCore.Authentication.OAuth.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Authentication.OAuth.Tests/Volo.Abp.AspNetCore.Authentication.OAuth.Tests.csproj index e1253f04c3..0d170148d4 100644 --- a/framework/test/Volo.Abp.AspNetCore.Authentication.OAuth.Tests/Volo.Abp.AspNetCore.Authentication.OAuth.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Authentication.OAuth.Tests/Volo.Abp.AspNetCore.Authentication.OAuth.Tests.csproj @@ -17,7 +17,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo.Abp.AspNetCore.MultiTenancy.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo.Abp.AspNetCore.MultiTenancy.Tests.csproj index a24f7796c9..9e7bf68457 100644 --- a/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo.Abp.AspNetCore.MultiTenancy.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo.Abp.AspNetCore.MultiTenancy.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj index bb841bc085..b3842f7271 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj @@ -20,7 +20,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests.csproj index 53e92dc13a..f1fa33a3b3 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests.csproj @@ -19,7 +19,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.csproj b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.csproj index f0301e04fe..ccbffb47f4 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.csproj @@ -8,7 +8,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Tests/Volo.Abp.AspNetCore.Mvc.UI.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Tests/Volo.Abp.AspNetCore.Mvc.UI.Tests.csproj index fb8b7abd07..92e5e21867 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Tests/Volo.Abp.AspNetCore.Mvc.UI.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Tests/Volo.Abp.AspNetCore.Mvc.UI.Tests.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.csproj b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.csproj index 7a95c77246..4c328a670f 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo.Abp.AspNetCore.Mvc.Versioning.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo.Abp.AspNetCore.Mvc.Versioning.Tests.csproj index 1d3fbf892f..e519e733de 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo.Abp.AspNetCore.Mvc.Versioning.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo.Abp.AspNetCore.Mvc.Versioning.Tests.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo.Abp.AspNetCore.Serilog.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo.Abp.AspNetCore.Serilog.Tests.csproj index 02cf2264a4..77c291f0a0 100644 --- a/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo.Abp.AspNetCore.Serilog.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo.Abp.AspNetCore.Serilog.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.SignalR.Tests/Volo.Abp.AspNetCore.SignalR.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.SignalR.Tests/Volo.Abp.AspNetCore.SignalR.Tests.csproj index 8e1ab29329..3bf5a6badd 100644 --- a/framework/test/Volo.Abp.AspNetCore.SignalR.Tests/Volo.Abp.AspNetCore.SignalR.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.SignalR.Tests/Volo.Abp.AspNetCore.SignalR.Tests.csproj @@ -8,7 +8,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.Tests/Volo.Abp.AspNetCore.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Tests/Volo.Abp.AspNetCore.Tests.csproj index 8dc3153efb..5becdbc672 100644 --- a/framework/test/Volo.Abp.AspNetCore.Tests/Volo.Abp.AspNetCore.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Tests/Volo.Abp.AspNetCore.Tests.csproj @@ -25,7 +25,7 @@ - + diff --git a/framework/test/Volo.Abp.Auditing.Tests/Volo.Abp.Auditing.Tests.csproj b/framework/test/Volo.Abp.Auditing.Tests/Volo.Abp.Auditing.Tests.csproj index 3c11330181..2b74dd0a58 100644 --- a/framework/test/Volo.Abp.Auditing.Tests/Volo.Abp.Auditing.Tests.csproj +++ b/framework/test/Volo.Abp.Auditing.Tests/Volo.Abp.Auditing.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo.Abp.Authorization.Tests.csproj b/framework/test/Volo.Abp.Authorization.Tests/Volo.Abp.Authorization.Tests.csproj index 3249de2c50..1d3e4b5dfd 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo.Abp.Authorization.Tests.csproj +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo.Abp.Authorization.Tests.csproj @@ -14,7 +14,7 @@ - + diff --git a/framework/test/Volo.Abp.AutoMapper.Tests/Volo.Abp.AutoMapper.Tests.csproj b/framework/test/Volo.Abp.AutoMapper.Tests/Volo.Abp.AutoMapper.Tests.csproj index 6178700db1..1d3d553047 100644 --- a/framework/test/Volo.Abp.AutoMapper.Tests/Volo.Abp.AutoMapper.Tests.csproj +++ b/framework/test/Volo.Abp.AutoMapper.Tests/Volo.Abp.AutoMapper.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/framework/test/Volo.Abp.Autofac.Tests/Volo.Abp.Autofac.Tests.csproj b/framework/test/Volo.Abp.Autofac.Tests/Volo.Abp.Autofac.Tests.csproj index 7854d82b82..c8d0672d13 100644 --- a/framework/test/Volo.Abp.Autofac.Tests/Volo.Abp.Autofac.Tests.csproj +++ b/framework/test/Volo.Abp.Autofac.Tests/Volo.Abp.Autofac.Tests.csproj @@ -14,7 +14,7 @@ - + diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo.Abp.BackgroundJobs.Tests.csproj b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo.Abp.BackgroundJobs.Tests.csproj index c8763de75d..ca7f94918d 100644 --- a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo.Abp.BackgroundJobs.Tests.csproj +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo.Abp.BackgroundJobs.Tests.csproj @@ -13,7 +13,7 @@ - + diff --git a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo.Abp.BlobStoring.Azure.Tests.csproj b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo.Abp.BlobStoring.Azure.Tests.csproj index ff97ea97d3..09a4861297 100644 --- a/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo.Abp.BlobStoring.Azure.Tests.csproj +++ b/framework/test/Volo.Abp.BlobStoring.Azure.Tests/Volo.Abp.BlobStoring.Azure.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/framework/test/Volo.Abp.BlobStoring.FileSystem.Tests/Volo.Abp.BlobStoring.FileSystem.Tests.csproj b/framework/test/Volo.Abp.BlobStoring.FileSystem.Tests/Volo.Abp.BlobStoring.FileSystem.Tests.csproj index b2741af89a..93165fa05a 100644 --- a/framework/test/Volo.Abp.BlobStoring.FileSystem.Tests/Volo.Abp.BlobStoring.FileSystem.Tests.csproj +++ b/framework/test/Volo.Abp.BlobStoring.FileSystem.Tests/Volo.Abp.BlobStoring.FileSystem.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/framework/test/Volo.Abp.BlobStoring.Tests/Volo.Abp.BlobStoring.Tests.csproj b/framework/test/Volo.Abp.BlobStoring.Tests/Volo.Abp.BlobStoring.Tests.csproj index d9535ff176..130f95bb77 100644 --- a/framework/test/Volo.Abp.BlobStoring.Tests/Volo.Abp.BlobStoring.Tests.csproj +++ b/framework/test/Volo.Abp.BlobStoring.Tests/Volo.Abp.BlobStoring.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/framework/test/Volo.Abp.Caching.Tests/Volo.Abp.Caching.Tests.csproj b/framework/test/Volo.Abp.Caching.Tests/Volo.Abp.Caching.Tests.csproj index 698278ee4c..1213685332 100644 --- a/framework/test/Volo.Abp.Caching.Tests/Volo.Abp.Caching.Tests.csproj +++ b/framework/test/Volo.Abp.Caching.Tests/Volo.Abp.Caching.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/framework/test/Volo.Abp.Castle.Core.Tests/Volo.Abp.Castle.Core.Tests.csproj b/framework/test/Volo.Abp.Castle.Core.Tests/Volo.Abp.Castle.Core.Tests.csproj index 23564716da..f16f39a6eb 100644 --- a/framework/test/Volo.Abp.Castle.Core.Tests/Volo.Abp.Castle.Core.Tests.csproj +++ b/framework/test/Volo.Abp.Castle.Core.Tests/Volo.Abp.Castle.Core.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/framework/test/Volo.Abp.Cli.Core.Tests/Volo.Abp.Cli.Core.Tests.csproj b/framework/test/Volo.Abp.Cli.Core.Tests/Volo.Abp.Cli.Core.Tests.csproj index 97aaa8a83f..d13f50b93b 100644 --- a/framework/test/Volo.Abp.Cli.Core.Tests/Volo.Abp.Cli.Core.Tests.csproj +++ b/framework/test/Volo.Abp.Cli.Core.Tests/Volo.Abp.Cli.Core.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/framework/test/Volo.Abp.Core.Tests/Volo.Abp.Core.Tests.csproj b/framework/test/Volo.Abp.Core.Tests/Volo.Abp.Core.Tests.csproj index bd646adf95..6be0cb02ab 100644 --- a/framework/test/Volo.Abp.Core.Tests/Volo.Abp.Core.Tests.csproj +++ b/framework/test/Volo.Abp.Core.Tests/Volo.Abp.Core.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/framework/test/Volo.Abp.Dapper.Tests/Volo.Abp.Dapper.Tests.csproj b/framework/test/Volo.Abp.Dapper.Tests/Volo.Abp.Dapper.Tests.csproj index 1bb64ef52d..4402f1e9a8 100644 --- a/framework/test/Volo.Abp.Dapper.Tests/Volo.Abp.Dapper.Tests.csproj +++ b/framework/test/Volo.Abp.Dapper.Tests/Volo.Abp.Dapper.Tests.csproj @@ -13,7 +13,7 @@ - + diff --git a/framework/test/Volo.Abp.Data.Tests/Volo.Abp.Data.Tests.csproj b/framework/test/Volo.Abp.Data.Tests/Volo.Abp.Data.Tests.csproj index 35d7ad3950..c35edc1148 100644 --- a/framework/test/Volo.Abp.Data.Tests/Volo.Abp.Data.Tests.csproj +++ b/framework/test/Volo.Abp.Data.Tests/Volo.Abp.Data.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/framework/test/Volo.Abp.Ddd.Tests/Volo.Abp.Ddd.Tests.csproj b/framework/test/Volo.Abp.Ddd.Tests/Volo.Abp.Ddd.Tests.csproj index cb917cea72..3422dcbcf6 100644 --- a/framework/test/Volo.Abp.Ddd.Tests/Volo.Abp.Ddd.Tests.csproj +++ b/framework/test/Volo.Abp.Ddd.Tests/Volo.Abp.Ddd.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/Entity_Tests.cs b/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/Entity_Tests.cs new file mode 100644 index 0000000000..779ac3fe49 --- /dev/null +++ b/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/Entity_Tests.cs @@ -0,0 +1,139 @@ +using System; +using Shouldly; +using Volo.Abp.MultiTenancy; +using Xunit; + +namespace Volo.Abp.Domain.Entities +{ + public class Entity_Tests + { + [Fact] + public void EntityEquals_Should_Return_True_For_Same_Keys() + { + var idValue1 = Guid.NewGuid(); + var idValue2 = Guid.NewGuid(); + + new Person(idValue1).EntityEquals(new Person(idValue1)).ShouldBeTrue(); + + new Car(42).EntityEquals(new Car(42)).ShouldBeTrue(); + + new Product("a").EntityEquals(new Product("a")).ShouldBeTrue(); + + new Phone(idValue1, "123").EntityEquals(new Phone(idValue1, "123")).ShouldBeTrue(); + } + + [Fact] + public void EntityEquals_Should_Return_False_For_Different_Keys() + { + var idValue1 = Guid.NewGuid(); + var idValue2 = Guid.NewGuid(); + + new Person(idValue1).EntityEquals(new Person()).ShouldBeFalse(); + new Person(idValue1).EntityEquals(new Person(idValue2)).ShouldBeFalse(); + + new Car(42).EntityEquals(new Car()).ShouldBeFalse(); + new Car(42).EntityEquals(new Car(43)).ShouldBeFalse(); + + new Product("a").EntityEquals(new Product()).ShouldBeFalse(); + new Product("a").EntityEquals(new Product("b")).ShouldBeFalse(); + + new Phone(idValue1, "123").EntityEquals(new Phone()).ShouldBeFalse(); + new Phone(idValue1, "123").EntityEquals(new Phone(idValue1, null)).ShouldBeFalse(); + new Phone(idValue1, "123").EntityEquals(new Phone(idValue1, "321")).ShouldBeFalse(); + } + + [Fact] + public void EntityEquals_Should_Return_False_For_Both_Default_Keys() + { + new Person().EntityEquals(new Person()).ShouldBeFalse(); + + new Car().EntityEquals(new Car()).ShouldBeFalse(); + + new Product().EntityEquals(new Product()).ShouldBeFalse(); + + new Phone().EntityEquals(new Phone()).ShouldBeFalse(); + } + + [Fact] + public void Different_Tenants_With_Same_Keys_Considered_As_Different_Objects() + { + var tenantId1 = Guid.NewGuid(); + var tenantId2 = Guid.NewGuid(); + + new Car(42, tenantId1).EntityEquals(new Car(42)).ShouldBeFalse(); + new Car(42).EntityEquals(new Car(42, tenantId2)).ShouldBeFalse(); + new Car(42, tenantId1).EntityEquals(new Car(42, tenantId2)).ShouldBeFalse(); + } + + [Fact] + public void Same_Tenants_With_Same_Keys_Considered_As_Same_Objects() + { + var tenantId1 = Guid.NewGuid(); + + new Car(42).EntityEquals(new Car(42)).ShouldBeTrue(); + new Car(42, tenantId1).EntityEquals(new Car(42, tenantId1)).ShouldBeTrue(); + } + + public class Person : Entity + { + public Person() + { + } + + public Person(Guid id) + : base(id) + { + } + } + + public class Car : Entity, IMultiTenant + { + public Guid? TenantId { get; } + + public Car() + { + } + + public Car(int id, Guid? tenantId = null) + : base(id) + { + TenantId = tenantId; + } + } + + public class Product : Entity + { + public Product() + { + } + + public Product(string id) + : base(id) + { + } + } + + public class Phone : Entity + { + public Guid PersonId { get; set; } + + public string Number { get; set; } + + public Phone() + { + + } + + public Phone(Guid personId, string number) + { + PersonId = personId; + Number = number; + } + + public override object[] GetKeys() + { + return new Object[] {PersonId, Number}; + } + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorListExtensions_Tests.cs b/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorListExtensions_Tests.cs new file mode 100644 index 0000000000..9949d23f1f --- /dev/null +++ b/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Entities/Events/Distributed/AutoEntityDistributedEventSelectorListExtensions_Tests.cs @@ -0,0 +1,22 @@ +using Shouldly; +using Xunit; + +namespace Volo.Abp.Domain.Entities.Events.Distributed +{ + public class AutoEntityDistributedEventSelectorListExtensions_Tests + { + [Fact] + public void Add_Entity() + { + var selectors = new AutoEntityDistributedEventSelectorList(); + selectors.Add(); + + selectors.IsMatch(typeof(MyEntity)).ShouldBeTrue(); + } + + private class MyEntity : Entity + { + + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo.Abp.Emailing.Tests.csproj b/framework/test/Volo.Abp.Emailing.Tests/Volo.Abp.Emailing.Tests.csproj index 030eddb65a..23dd953416 100644 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo.Abp.Emailing.Tests.csproj +++ b/framework/test/Volo.Abp.Emailing.Tests/Volo.Abp.Emailing.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/tr.json b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/tr.json new file mode 100644 index 0000000000..6c3c94cfdf --- /dev/null +++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/tr.json @@ -0,0 +1,6 @@ +{ + "culture": "tr", + "texts": { + "hello": "Merhaba" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo.Abp.EntityFrameworkCore.Tests.csproj b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo.Abp.EntityFrameworkCore.Tests.csproj index a154e6acaf..84fcc32477 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo.Abp.EntityFrameworkCore.Tests.csproj +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo.Abp.EntityFrameworkCore.Tests.csproj @@ -16,7 +16,7 @@ - + diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DomainEvents/EntityChangeEvents_Tests.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DomainEvents/EntityChangeEvents_Tests.cs index 2b94ee1ed9..9f4b67d089 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DomainEvents/EntityChangeEvents_Tests.cs +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DomainEvents/EntityChangeEvents_Tests.cs @@ -4,6 +4,6 @@ namespace Volo.Abp.EntityFrameworkCore.DomainEvents { public class EntityChangeEvents_Tests : EntityChangeEvents_Tests { - + } } diff --git a/framework/test/Volo.Abp.EventBus.Tests/Volo.Abp.EventBus.Tests.csproj b/framework/test/Volo.Abp.EventBus.Tests/Volo.Abp.EventBus.Tests.csproj index adeefbd45b..f45812c4a6 100644 --- a/framework/test/Volo.Abp.EventBus.Tests/Volo.Abp.EventBus.Tests.csproj +++ b/framework/test/Volo.Abp.EventBus.Tests/Volo.Abp.EventBus.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/framework/test/Volo.Abp.Features.Tests/Volo.Abp.Features.Tests.csproj b/framework/test/Volo.Abp.Features.Tests/Volo.Abp.Features.Tests.csproj index bc375d9406..d5ea171e35 100644 --- a/framework/test/Volo.Abp.Features.Tests/Volo.Abp.Features.Tests.csproj +++ b/framework/test/Volo.Abp.Features.Tests/Volo.Abp.Features.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/framework/test/Volo.Abp.FluentValidation.Tests/Volo.Abp.FluentValidation.Tests.csproj b/framework/test/Volo.Abp.FluentValidation.Tests/Volo.Abp.FluentValidation.Tests.csproj index 3c91d940e5..2ee95269ae 100644 --- a/framework/test/Volo.Abp.FluentValidation.Tests/Volo.Abp.FluentValidation.Tests.csproj +++ b/framework/test/Volo.Abp.FluentValidation.Tests/Volo.Abp.FluentValidation.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/framework/test/Volo.Abp.Http.Client.IdentityModel.Web.Tests/Volo.Abp.Http.Client.IdentityModel.Web.Tests.csproj b/framework/test/Volo.Abp.Http.Client.IdentityModel.Web.Tests/Volo.Abp.Http.Client.IdentityModel.Web.Tests.csproj index 704c3b57aa..78518bdda3 100644 --- a/framework/test/Volo.Abp.Http.Client.IdentityModel.Web.Tests/Volo.Abp.Http.Client.IdentityModel.Web.Tests.csproj +++ b/framework/test/Volo.Abp.Http.Client.IdentityModel.Web.Tests/Volo.Abp.Http.Client.IdentityModel.Web.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo.Abp.Http.Client.Tests.csproj b/framework/test/Volo.Abp.Http.Client.Tests/Volo.Abp.Http.Client.Tests.csproj index 193df5db4f..07708ce189 100644 --- a/framework/test/Volo.Abp.Http.Client.Tests/Volo.Abp.Http.Client.Tests.csproj +++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo.Abp.Http.Client.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/framework/test/Volo.Abp.Ldap.Tests/Volo.Abp.Ldap.Tests.csproj b/framework/test/Volo.Abp.Ldap.Tests/Volo.Abp.Ldap.Tests.csproj index c0854a7633..3c1f9c96db 100644 --- a/framework/test/Volo.Abp.Ldap.Tests/Volo.Abp.Ldap.Tests.csproj +++ b/framework/test/Volo.Abp.Ldap.Tests/Volo.Abp.Ldap.Tests.csproj @@ -8,7 +8,7 @@ - + diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo.Abp.Localization.Tests.csproj b/framework/test/Volo.Abp.Localization.Tests/Volo.Abp.Localization.Tests.csproj index 20c92c8cf8..56abd36ebb 100644 --- a/framework/test/Volo.Abp.Localization.Tests/Volo.Abp.Localization.Tests.csproj +++ b/framework/test/Volo.Abp.Localization.Tests/Volo.Abp.Localization.Tests.csproj @@ -14,7 +14,7 @@ - + diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpLocalization_Tests.cs b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpLocalization_Tests.cs index 961f1ba0a4..71c2fafe2e 100644 --- a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpLocalization_Tests.cs +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpLocalization_Tests.cs @@ -1,6 +1,5 @@ using System.Globalization; using System.Linq; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; using Shouldly; using Volo.Abp.Localization.TestResources.Base.CountryNames; diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/tr.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/tr.json index 1f38b5c8d4..a6b6ce2a44 100644 --- a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/tr.json +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/tr.json @@ -1,6 +1,7 @@ -{ +{ "culture": "tr", "texts": { - "USA": "Amerika Birleşik Devletleri" + "USA": "Amerika Birleşik Devletleri", + "Brazil": "Brezilya" } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/tr.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/tr.json new file mode 100644 index 0000000000..4a1cb24c25 --- /dev/null +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/tr.json @@ -0,0 +1,7 @@ +{ + "culture": "tr", + "texts": { + "ThisFieldIsRequired": "Bu alan zorunludur", + "MaxLenghtErrorMessage": "Bu alan maksimum '{0}' karakter olabilir" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/tr.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/tr.json index fa2d23246b..ee1900e150 100644 --- a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/tr.json +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/tr.json @@ -1,9 +1,10 @@ -{ +{ "culture": "tr", "texts": { "Hello {0}.": "Merhaba {0}.", "Car": "Araba", "CarPlural": "Araba", + "MaxLenghtErrorMessage": "Bu alanın uzunluğu maksimum '{0}' karakter olabilir", "Universe": "Evren" } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/tr.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/tr.json new file mode 100644 index 0000000000..7023061d35 --- /dev/null +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/tr.json @@ -0,0 +1,6 @@ +{ + "culture": "tr", + "texts": { + + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.MailKit.Tests/Volo.Abp.MailKit.Tests.csproj b/framework/test/Volo.Abp.MailKit.Tests/Volo.Abp.MailKit.Tests.csproj index bc5d991884..31c7001db5 100644 --- a/framework/test/Volo.Abp.MailKit.Tests/Volo.Abp.MailKit.Tests.csproj +++ b/framework/test/Volo.Abp.MailKit.Tests/Volo.Abp.MailKit.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/framework/test/Volo.Abp.MemoryDb.Tests/Volo.Abp.MemoryDb.Tests.csproj b/framework/test/Volo.Abp.MemoryDb.Tests/Volo.Abp.MemoryDb.Tests.csproj index 9b6adc9442..372ebd68f4 100644 --- a/framework/test/Volo.Abp.MemoryDb.Tests/Volo.Abp.MemoryDb.Tests.csproj +++ b/framework/test/Volo.Abp.MemoryDb.Tests/Volo.Abp.MemoryDb.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/framework/test/Volo.Abp.Minify.Tests/Volo.Abp.Minify.Tests.csproj b/framework/test/Volo.Abp.Minify.Tests/Volo.Abp.Minify.Tests.csproj index 69b159dd0f..2c14d9fba4 100644 --- a/framework/test/Volo.Abp.Minify.Tests/Volo.Abp.Minify.Tests.csproj +++ b/framework/test/Volo.Abp.Minify.Tests/Volo.Abp.Minify.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo.Abp.MongoDB.Tests.csproj b/framework/test/Volo.Abp.MongoDB.Tests/Volo.Abp.MongoDB.Tests.csproj index dc35828937..97758b7880 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo.Abp.MongoDB.Tests.csproj +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo.Abp.MongoDB.Tests.csproj @@ -16,7 +16,7 @@ - + diff --git a/framework/test/Volo.Abp.MultiTenancy.Tests/Volo.Abp.MultiTenancy.Tests.csproj b/framework/test/Volo.Abp.MultiTenancy.Tests/Volo.Abp.MultiTenancy.Tests.csproj index 1c9ab1ab4b..3d95f00a8b 100644 --- a/framework/test/Volo.Abp.MultiTenancy.Tests/Volo.Abp.MultiTenancy.Tests.csproj +++ b/framework/test/Volo.Abp.MultiTenancy.Tests/Volo.Abp.MultiTenancy.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/framework/test/Volo.Abp.ObjectExtending.Tests/Volo.Abp.ObjectExtending.Tests.csproj b/framework/test/Volo.Abp.ObjectExtending.Tests/Volo.Abp.ObjectExtending.Tests.csproj index 0a18e0c44b..212eeb7d5b 100644 --- a/framework/test/Volo.Abp.ObjectExtending.Tests/Volo.Abp.ObjectExtending.Tests.csproj +++ b/framework/test/Volo.Abp.ObjectExtending.Tests/Volo.Abp.ObjectExtending.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/framework/test/Volo.Abp.ObjectMapping.Tests/Volo.Abp.ObjectMapping.Tests.csproj b/framework/test/Volo.Abp.ObjectMapping.Tests/Volo.Abp.ObjectMapping.Tests.csproj index c4b54f9efd..23c59ef064 100644 --- a/framework/test/Volo.Abp.ObjectMapping.Tests/Volo.Abp.ObjectMapping.Tests.csproj +++ b/framework/test/Volo.Abp.ObjectMapping.Tests/Volo.Abp.ObjectMapping.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/framework/test/Volo.Abp.Security.Tests/Volo.Abp.Security.Tests.csproj b/framework/test/Volo.Abp.Security.Tests/Volo.Abp.Security.Tests.csproj index 6e99e2d1e8..41d152d1cb 100644 --- a/framework/test/Volo.Abp.Security.Tests/Volo.Abp.Security.Tests.csproj +++ b/framework/test/Volo.Abp.Security.Tests/Volo.Abp.Security.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/framework/test/Volo.Abp.Serialization.Tests/Volo.Abp.Serialization.Tests.csproj b/framework/test/Volo.Abp.Serialization.Tests/Volo.Abp.Serialization.Tests.csproj index 36df9d0a60..3efd1d9db7 100644 --- a/framework/test/Volo.Abp.Serialization.Tests/Volo.Abp.Serialization.Tests.csproj +++ b/framework/test/Volo.Abp.Serialization.Tests/Volo.Abp.Serialization.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/framework/test/Volo.Abp.Settings.Tests/Volo.Abp.Settings.Tests.csproj b/framework/test/Volo.Abp.Settings.Tests/Volo.Abp.Settings.Tests.csproj index 70d52138a3..fadf2659d0 100644 --- a/framework/test/Volo.Abp.Settings.Tests/Volo.Abp.Settings.Tests.csproj +++ b/framework/test/Volo.Abp.Settings.Tests/Volo.Abp.Settings.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/framework/test/Volo.Abp.Specifications.Tests/Volo.Abp.Specifications.Tests.csproj b/framework/test/Volo.Abp.Specifications.Tests/Volo.Abp.Specifications.Tests.csproj index 0ddc58ea96..b44ee82aae 100644 --- a/framework/test/Volo.Abp.Specifications.Tests/Volo.Abp.Specifications.Tests.csproj +++ b/framework/test/Volo.Abp.Specifications.Tests/Volo.Abp.Specifications.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/framework/test/Volo.Abp.TestApp.Tests/Volo.Abp.TestApp.Tests.csproj b/framework/test/Volo.Abp.TestApp.Tests/Volo.Abp.TestApp.Tests.csproj index b733889bf0..0ff64ec1d8 100644 --- a/framework/test/Volo.Abp.TestApp.Tests/Volo.Abp.TestApp.Tests.csproj +++ b/framework/test/Volo.Abp.TestApp.Tests/Volo.Abp.TestApp.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/framework/test/Volo.Abp.TestApp/Volo.Abp.TestApp.csproj b/framework/test/Volo.Abp.TestApp/Volo.Abp.TestApp.csproj index c2d9ab2007..35d5e3b71a 100644 --- a/framework/test/Volo.Abp.TestApp/Volo.Abp.TestApp.csproj +++ b/framework/test/Volo.Abp.TestApp/Volo.Abp.TestApp.csproj @@ -14,7 +14,7 @@ - + diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/EntityChangeEvents_Tests.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/EntityChangeEvents_Tests.cs index fe4e0862f3..cb16a46439 100644 --- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/EntityChangeEvents_Tests.cs +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/EntityChangeEvents_Tests.cs @@ -84,5 +84,44 @@ namespace Volo.Abp.TestApp.Testing createdEventTriggered.ShouldBeTrue(); createdEtoTriggered.ShouldBeTrue(); } + + [Fact] + public async Task Multiple_Update_Should_Result_With_Single_Updated_Event_In_The_Same_Uow() + { + var personId = Guid.NewGuid(); + await PersonRepository.InsertAsync(new Person(personId, Guid.NewGuid().ToString("D"), 42)); + + var updateEventCount = 0; + var updatedAge = 0; + + DistributedEventBus.Subscribe>(eto => + { + updateEventCount++; + updatedAge = eto.Entity.Age; + return Task.CompletedTask; + }); + + using (var uow = GetRequiredService().Begin()) + { + var person = await PersonRepository.GetAsync(personId); + + person.Age = 43; + await PersonRepository.UpdateAsync(person, autoSave: true); + updateEventCount.ShouldBe(0); + + person.Age = 44; + await PersonRepository.UpdateAsync(person, autoSave: true); + updateEventCount.ShouldBe(0); + + person.Age = 45; + await PersonRepository.UpdateAsync(person, autoSave: true); + updateEventCount.ShouldBe(0); + + await uow.CompleteAsync(); + } + + updateEventCount.ShouldBe(1); + updatedAge.ShouldBe(45); + } } } diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj b/framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj index 0d230552e8..0895567843 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj @@ -19,7 +19,7 @@ - + diff --git a/framework/test/Volo.Abp.UI.Navigation.Tests/Volo.Abp.UI.Navigation.Tests.csproj b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo.Abp.UI.Navigation.Tests.csproj index bf48039303..2ba5372364 100644 --- a/framework/test/Volo.Abp.UI.Navigation.Tests/Volo.Abp.UI.Navigation.Tests.csproj +++ b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo.Abp.UI.Navigation.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/framework/test/Volo.Abp.Uow.Tests/Volo.Abp.Uow.Tests.csproj b/framework/test/Volo.Abp.Uow.Tests/Volo.Abp.Uow.Tests.csproj index 32bd3e4af5..c6b401eec1 100644 --- a/framework/test/Volo.Abp.Uow.Tests/Volo.Abp.Uow.Tests.csproj +++ b/framework/test/Volo.Abp.Uow.Tests/Volo.Abp.Uow.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/framework/test/Volo.Abp.Validation.Tests/Volo.Abp.Validation.Tests.csproj b/framework/test/Volo.Abp.Validation.Tests/Volo.Abp.Validation.Tests.csproj index 7bf3df7ca5..13f57717d5 100644 --- a/framework/test/Volo.Abp.Validation.Tests/Volo.Abp.Validation.Tests.csproj +++ b/framework/test/Volo.Abp.Validation.Tests/Volo.Abp.Validation.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo.Abp.VirtualFileSystem.Tests.csproj b/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo.Abp.VirtualFileSystem.Tests.csproj index 7dcfdc83c5..9f8f904aa4 100644 --- a/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo.Abp.VirtualFileSystem.Tests.csproj +++ b/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo.Abp.VirtualFileSystem.Tests.csproj @@ -14,7 +14,7 @@ - + diff --git a/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/tr.json b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/tr.json index 44cebc1190..60d5f40634 100644 --- a/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/tr.json +++ b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/tr.json @@ -1,4 +1,4 @@ -{ +{ "culture": "tr", "texts": { "UserName": "Kullanıcı adı", @@ -11,10 +11,12 @@ "InvalidUserNameOrPassword": "Kullanıcı adı ya da şifre geçersiz!", "LoginIsNotAllowed": "Giriş yapamazsınız! E-posta adresinizi ya da telefon numaranızı doğrulamanız gerekiyor.", "SelfRegistrationDisabledMessage": "Bu uygulama için kullanıcıların kendi kendilerine kaydolmaları engellenmiştir. Yeni bir kullanıcı kaydetmek için lütfen uygulama yöneticisi ile iletişime geçin.", + "LocalLoginDisabledMessage": "Bu uygulama için local login devre dışı bırakılmıştır.", "Login": "Giriş yap", "Cancel": "İptal", "Register": "Kayıt ol", "AreYouANewUser": "Yeni bir kullanıcı mısınız?", + "AlreadyRegistered": "Zaten kayıtlı mı?", "InvalidLoginRequest": "Başarısız giriş isteği", "ThereAreNoLoginSchemesConfiguredForThisClient": "Bu client için konfigüre edilmiş giriş şeması bulunamadı.", "LogInUsingYourProviderAccount": "{0} hesabınızla giriş yapın.", @@ -34,6 +36,10 @@ "PasswordChanged": "Şifre değiştirildi", "NewPasswordConfirmFailed": "Lütfen yeni şifreyi onaylayın.", "Manage": "Manage", - "ManageYourProfile": "Profilinizi yönetin" + "ManageYourProfile": "Profilinizi yönetin", + "DisplayName:Abp.Account.IsSelfRegistrationEnabled": "self-registration etkin mi ?", + "Description:Abp.Account.IsSelfRegistrationEnabled": "Bir kullanıcının hesabı kendisi tarafından kaydedip kaydedememesidir.", + "DisplayName:Abp.Account.EnableLocalLogin": "Yerel bir hesapla kimlik doğrulaması", + "Description:Abp.Account.EnableLocalLogin": "Sunucunun, kullanıcıların yerel bir hesapla kimlik doğrulamasına izin verip vermeyeceğini belirtir." } } \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Application/Volo.Abp.Account.Application.csproj b/modules/account/src/Volo.Abp.Account.Application/Volo.Abp.Account.Application.csproj index 1ddc2323d1..a11fb89e1a 100644 --- a/modules/account/src/Volo.Abp.Account.Application/Volo.Abp.Account.Application.csproj +++ b/modules/account/src/Volo.Abp.Account.Application/Volo.Abp.Account.Application.csproj @@ -11,7 +11,7 @@ - + diff --git a/modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/Models/UserLoginInfo.cs b/modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/Models/UserLoginInfo.cs index fe86445a85..ef3f399477 100644 --- a/modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/Models/UserLoginInfo.cs +++ b/modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/Models/UserLoginInfo.cs @@ -17,7 +17,5 @@ namespace Volo.Abp.Account.Web.Areas.Account.Controllers.Models public string Password { get; set; } public bool RememberMe { get; set; } - - public Guid? TenanId { get; set; } } -} \ No newline at end of file +} diff --git a/modules/account/test/Volo.Abp.Account.Application.Tests/Volo.Abp.Account.Application.Tests.csproj b/modules/account/test/Volo.Abp.Account.Application.Tests/Volo.Abp.Account.Application.Tests.csproj index f4c7094d4f..779c2d2d25 100644 --- a/modules/account/test/Volo.Abp.Account.Application.Tests/Volo.Abp.Account.Application.Tests.csproj +++ b/modules/account/test/Volo.Abp.Account.Application.Tests/Volo.Abp.Account.Application.Tests.csproj @@ -6,13 +6,13 @@ - - - + + + - + diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests.csproj b/modules/audit-logging/test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests.csproj index c85e570040..6287d732e2 100644 --- a/modules/audit-logging/test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests.csproj +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests.csproj @@ -14,8 +14,8 @@ - - + + diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo.Abp.AuditLogging.MongoDB.Tests.csproj b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo.Abp.AuditLogging.MongoDB.Tests.csproj index ffc1906dce..34130bfca5 100644 --- a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo.Abp.AuditLogging.MongoDB.Tests.csproj +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo.Abp.AuditLogging.MongoDB.Tests.csproj @@ -13,7 +13,7 @@ - + diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo.Abp.AuditLogging.TestBase.csproj b/modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo.Abp.AuditLogging.TestBase.csproj index ced62e3c1b..e62925a488 100644 --- a/modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo.Abp.AuditLogging.TestBase.csproj +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo.Abp.AuditLogging.TestBase.csproj @@ -14,12 +14,12 @@ - - + + - + diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.Tests/Volo.Abp.AuditLogging.Tests.csproj b/modules/audit-logging/test/Volo.Abp.AuditLogging.Tests/Volo.Abp.AuditLogging.Tests.csproj index ccfb554d58..ab703cdca3 100644 --- a/modules/audit-logging/test/Volo.Abp.AuditLogging.Tests/Volo.Abp.AuditLogging.Tests.csproj +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.Tests/Volo.Abp.AuditLogging.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Volo.Abp.BackgroundJobs.DemoApp.Shared.csproj b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Volo.Abp.BackgroundJobs.DemoApp.Shared.csproj index 3c942ccf89..cf5ed0ce08 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Volo.Abp.BackgroundJobs.DemoApp.Shared.csproj +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Volo.Abp.BackgroundJobs.DemoApp.Shared.csproj @@ -7,7 +7,7 @@ - + diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/Volo.Abp.BackgroundJobs.DemoApp.csproj b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/Volo.Abp.BackgroundJobs.DemoApp.csproj index e6f1a834ec..0d8388c610 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/Volo.Abp.BackgroundJobs.DemoApp.csproj +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/Volo.Abp.BackgroundJobs.DemoApp.csproj @@ -6,7 +6,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.Domain.Tests/Volo.Abp.BackgroundJobs.Domain.Tests.csproj b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.Domain.Tests/Volo.Abp.BackgroundJobs.Domain.Tests.csproj index 1326240199..4c835cbd51 100644 --- a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.Domain.Tests/Volo.Abp.BackgroundJobs.Domain.Tests.csproj +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.Domain.Tests/Volo.Abp.BackgroundJobs.Domain.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests.csproj b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests.csproj index e419b3302a..3246aefa4f 100644 --- a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests.csproj +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests.csproj @@ -14,8 +14,8 @@ - - + + diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo.Abp.BackgroundJobs.MongoDB.Tests.csproj b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo.Abp.BackgroundJobs.MongoDB.Tests.csproj index 3878875e65..496f95b373 100644 --- a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo.Abp.BackgroundJobs.MongoDB.Tests.csproj +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo.Abp.BackgroundJobs.MongoDB.Tests.csproj @@ -13,7 +13,7 @@ - + diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.TestBase/Volo.Abp.BackgroundJobs.TestBase.csproj b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.TestBase/Volo.Abp.BackgroundJobs.TestBase.csproj index 8563f2b04a..46d6ea7b8e 100644 --- a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.TestBase/Volo.Abp.BackgroundJobs.TestBase.csproj +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.TestBase/Volo.Abp.BackgroundJobs.TestBase.csproj @@ -14,12 +14,12 @@ - - + + - + diff --git a/modules/blob-storing-database/host/BlobStoring.Database.Host.ConsoleApp/src/BlobStoring.Database.Host.ConsoleApp.ConsoleApp/BlobStoring.Database.Host.ConsoleApp.ConsoleApp.csproj b/modules/blob-storing-database/host/BlobStoring.Database.Host.ConsoleApp/src/BlobStoring.Database.Host.ConsoleApp.ConsoleApp/BlobStoring.Database.Host.ConsoleApp.ConsoleApp.csproj index 61af5fc4ce..43455e655a 100644 --- a/modules/blob-storing-database/host/BlobStoring.Database.Host.ConsoleApp/src/BlobStoring.Database.Host.ConsoleApp.ConsoleApp/BlobStoring.Database.Host.ConsoleApp.ConsoleApp.csproj +++ b/modules/blob-storing-database/host/BlobStoring.Database.Host.ConsoleApp/src/BlobStoring.Database.Host.ConsoleApp.ConsoleApp/BlobStoring.Database.Host.ConsoleApp.ConsoleApp.csproj @@ -20,13 +20,13 @@ - + - - + + diff --git a/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.Domain.Tests/Volo.Abp.BlobStoring.Database.Domain.Tests.csproj b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.Domain.Tests/Volo.Abp.BlobStoring.Database.Domain.Tests.csproj index 20de7c154e..a6ff223c3a 100644 --- a/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.Domain.Tests/Volo.Abp.BlobStoring.Database.Domain.Tests.csproj +++ b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.Domain.Tests/Volo.Abp.BlobStoring.Database.Domain.Tests.csproj @@ -6,7 +6,7 @@ - + diff --git a/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests.csproj b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests.csproj index 8bdc5080aa..04bdd5071a 100644 --- a/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests.csproj +++ b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests.csproj @@ -6,10 +6,10 @@ - - - - + + + + diff --git a/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.MongoDB.Tests/Volo.Abp.BlobStoring.Database.MongoDB.Tests.csproj b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.MongoDB.Tests/Volo.Abp.BlobStoring.Database.MongoDB.Tests.csproj index 9b37676068..48196ab38f 100644 --- a/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.MongoDB.Tests/Volo.Abp.BlobStoring.Database.MongoDB.Tests.csproj +++ b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.MongoDB.Tests/Volo.Abp.BlobStoring.Database.MongoDB.Tests.csproj @@ -6,7 +6,7 @@ - + diff --git a/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.TestBase/Volo.Abp.BlobStoring.Database.TestBase.csproj b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.TestBase/Volo.Abp.BlobStoring.Database.TestBase.csproj index 8dfa603e98..196cdce7bb 100644 --- a/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.TestBase/Volo.Abp.BlobStoring.Database.TestBase.csproj +++ b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.TestBase/Volo.Abp.BlobStoring.Database.TestBase.csproj @@ -6,12 +6,12 @@ - - + + - + diff --git a/modules/blogging/app/Volo.BloggingTestApp/Volo.BloggingTestApp.csproj b/modules/blogging/app/Volo.BloggingTestApp/Volo.BloggingTestApp.csproj index 6e269e702a..c264c00f41 100644 --- a/modules/blogging/app/Volo.BloggingTestApp/Volo.BloggingTestApp.csproj +++ b/modules/blogging/app/Volo.BloggingTestApp/Volo.BloggingTestApp.csproj @@ -19,7 +19,7 @@ - + diff --git a/modules/blogging/src/Volo.Blogging.Admin.Web/Volo.Blogging.Admin.Web.csproj b/modules/blogging/src/Volo.Blogging.Admin.Web/Volo.Blogging.Admin.Web.csproj index d15cf9c770..9037420f3f 100644 --- a/modules/blogging/src/Volo.Blogging.Admin.Web/Volo.Blogging.Admin.Web.csproj +++ b/modules/blogging/src/Volo.Blogging.Admin.Web/Volo.Blogging.Admin.Web.csproj @@ -19,7 +19,7 @@ - + diff --git a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/tr.json b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/tr.json index b4b6cba0be..78e18601ff 100644 --- a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/tr.json +++ b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/tr.json @@ -1,4 +1,4 @@ -{ +{ "culture": "tr", "texts": { "Menu:Blogs": "Bloglar", @@ -20,7 +20,6 @@ "SeeAll": "Hepsini Gör", "PopularTags": "Popüler Etiketler", "WiewsWithCount": "{0} görüntüleme", - "ShareOnTwitter": "Twitter'da paylaş", "LastPosts": "Son Yazılar", "LeaveComment": "Yorum Bırak", "TagsInThisArticle": "Makalenin Etiketleri", @@ -33,6 +32,7 @@ "AreYouSure": "Emin misiniz?", "CommentWithCount": "{0} yorum", "Comment": "Yorum", + "ShareOnTwitter": "Twitter'da paylaş", "CoverImage": "Kapak resmi", "CreateANewPost": "Yeni Yazı oluştur", "CreateANewBlog": "Yeni Blog Ekle", @@ -43,6 +43,7 @@ "Description": "Açıklama", "Blogs": "Bloglar", "Tags": "Etiketler", - "ShareOn": "Paylaş" + "ShareOn": "Paylaş", + "TitleLengthWarning": "Başlığınınz SEO dostu olabilmesi için 60 karakterden az olmasını sağlayın!" } } \ No newline at end of file diff --git a/modules/blogging/src/Volo.Blogging.Web/Volo.Blogging.Web.csproj b/modules/blogging/src/Volo.Blogging.Web/Volo.Blogging.Web.csproj index 3760fa0539..e26b58d550 100644 --- a/modules/blogging/src/Volo.Blogging.Web/Volo.Blogging.Web.csproj +++ b/modules/blogging/src/Volo.Blogging.Web/Volo.Blogging.Web.csproj @@ -19,7 +19,7 @@ - + diff --git a/modules/blogging/test/Volo.Blogging.Application.Tests/Volo.Blogging.Application.Tests.csproj b/modules/blogging/test/Volo.Blogging.Application.Tests/Volo.Blogging.Application.Tests.csproj index 2bc4009d26..6776e49a9c 100644 --- a/modules/blogging/test/Volo.Blogging.Application.Tests/Volo.Blogging.Application.Tests.csproj +++ b/modules/blogging/test/Volo.Blogging.Application.Tests/Volo.Blogging.Application.Tests.csproj @@ -6,7 +6,7 @@ - + diff --git a/modules/blogging/test/Volo.Blogging.Domain.Tests/Volo.Blogging.Domain.Tests.csproj b/modules/blogging/test/Volo.Blogging.Domain.Tests/Volo.Blogging.Domain.Tests.csproj index 4c77689067..776aaf3657 100644 --- a/modules/blogging/test/Volo.Blogging.Domain.Tests/Volo.Blogging.Domain.Tests.csproj +++ b/modules/blogging/test/Volo.Blogging.Domain.Tests/Volo.Blogging.Domain.Tests.csproj @@ -2,11 +2,11 @@ netcoreapp3.1 - + - + diff --git a/modules/blogging/test/Volo.Blogging.EntityFrameworkCore.Tests/Volo.Blogging.EntityFrameworkCore.Tests.csproj b/modules/blogging/test/Volo.Blogging.EntityFrameworkCore.Tests/Volo.Blogging.EntityFrameworkCore.Tests.csproj index 1061e14347..01d894de88 100644 --- a/modules/blogging/test/Volo.Blogging.EntityFrameworkCore.Tests/Volo.Blogging.EntityFrameworkCore.Tests.csproj +++ b/modules/blogging/test/Volo.Blogging.EntityFrameworkCore.Tests/Volo.Blogging.EntityFrameworkCore.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo.Blogging.MongoDB.Tests.csproj b/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo.Blogging.MongoDB.Tests.csproj index d58c4ce66f..8eaa145ee7 100644 --- a/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo.Blogging.MongoDB.Tests.csproj +++ b/modules/blogging/test/Volo.Blogging.MongoDB.Tests/Volo.Blogging.MongoDB.Tests.csproj @@ -6,7 +6,7 @@ - + diff --git a/modules/blogging/test/Volo.Blogging.TestBase/Volo.Blogging.TestBase.csproj b/modules/blogging/test/Volo.Blogging.TestBase/Volo.Blogging.TestBase.csproj index 39cc02fafa..eae856530d 100644 --- a/modules/blogging/test/Volo.Blogging.TestBase/Volo.Blogging.TestBase.csproj +++ b/modules/blogging/test/Volo.Blogging.TestBase/Volo.Blogging.TestBase.csproj @@ -12,12 +12,12 @@ - - + + - + diff --git a/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/tr.json b/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/tr.json index 8f49c6e952..c88e95867d 100644 --- a/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/tr.json +++ b/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/tr.json @@ -1,6 +1,7 @@ -{ +{ "culture": "tr", "texts": { + "DocsTitle": "VoloDocs", "WelcomeVoloDocs": "VoloDocs Hoşgeldiniz!", "NoProjectWarning": "Henüz bir proje yok!", "CreateYourFirstProject": "İlk projenizi oluşturmak için tıklayın", diff --git a/modules/docs/app/VoloDocs.Web/VoloDocs.Web.csproj b/modules/docs/app/VoloDocs.Web/VoloDocs.Web.csproj index 9da16c65cf..2e06315603 100644 --- a/modules/docs/app/VoloDocs.Web/VoloDocs.Web.csproj +++ b/modules/docs/app/VoloDocs.Web/VoloDocs.Web.csproj @@ -19,7 +19,7 @@ - + diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/tr.json b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/tr.json index c40893e538..319a901004 100644 --- a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/tr.json +++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/tr.json @@ -1,4 +1,4 @@ -{ +{ "culture": "tr", "texts": { "Permission:DocumentManagement": "Döküman yönetimi", @@ -7,6 +7,7 @@ "Permission:Delete": "Sil", "Permission:Create": "Oluştur", "Permission:Documents": "Döküman", + "Menu:Documents": "Dokümanlar", "Menu:DocumentManagement": "Dökümanlar", "Menu:ProjectManagement": "Projeler", "CreateANewProject": "Yeni proje oluştur", @@ -29,8 +30,19 @@ "DisplayName:LatestVersionBranchName": "Son versiyon Branch adı", "DisplayName:GitHubRootUrl": "GitHub kök adresi", "DisplayName:GitHubAccessToken": "GitHub erişim token", + "DisplayName:GitHubUserAgent": "GitHub kullanıcı temsilcisi", "DisplayName:All": "Çekme bütün", "DisplayName:LanguageCode": "Dil kodu", - "DisplayName:Version": "versiyon" + "DisplayName:Version": "versiyon", + "Documents": "Dokümanlar", + "RemoveFromCache": "Önbellekten kaldır", + "Reindex": "Yeniden İndeksle", + "ReindexCompleted": "Yeniden indeksleme tamamlandı", + "RemovedFromCache": "Önbellekten kaldırıldı", + "RemoveFromCacheConfirmation": "Bu maddeyi önbellekten kaldırmak istediğiniz emin misiniz?", + "ReIndexDocumentConfirmation": "Bu maddeyi yeniden indekslemek istediğinize emin misiniz?", + "DeleteDocumentFromDbConfirmation": "Bu maddeyi veritabanından silmek istediğinize emin misiniz?", + "DeleteFromDatabase": "Veritabanından sil", + "Deleted": "Silindi" } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Domain/Volo.Docs.Domain.csproj b/modules/docs/src/Volo.Docs.Domain/Volo.Docs.Domain.csproj index 5331433e24..5b93ecdf8a 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo.Docs.Domain.csproj +++ b/modules/docs/src/Volo.Docs.Domain/Volo.Docs.Domain.csproj @@ -16,9 +16,9 @@ - - - + + + diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/tr.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/tr.json index 612274f95d..f41a049932 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/tr.json +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/tr.json @@ -1,4 +1,4 @@ -{ +{ "culture": "tr", "texts": { "Documents": "Dökümanlar", @@ -9,17 +9,30 @@ "Edit": "Düzenle", "LastEditTime": "Son Düzenleme", "Delete": "Sil", + "ClearCache": "Önbelleği temizle", + "ClearCacheConfirmationMessage": "\"{0}\" Projesinin tüm önbelliğini temizlemek istediğinize emin misiniz? ", + "ReIndexAllProjects": "Tüm projeleri yeniden indexle", + "ReIndexProject": "Projeyi yeniden indeksle", + "ReIndexProjectConfirmationMessage": "\"{0}\" Projesini yeniden insdekslemek istediğinize emin misiniz?", + "SuccessfullyReIndexProject": "\"{0}\" Projesi başarıyla yeniden indekslendi", + "ReIndexAllProjectConfirmationMessage": "Tüm projeleri yeniden indekslemek istediğinize emin misiniz?", + "SuccessfullyReIndexAllProject": "Tüm projeler başarıyla yeniden indekslendi", "InThisDocument": "Bu dökümanda", "GoToTop": "En üste çık", "Projects": "Proje(ler)", "NoProjectWarning": "Hiç proje yok!", "DocumentNotFound": "Aradığınız döküman bulunamadı!", + "ProjectNotFound": "Talep edilen proje bulunamadı!", "NavigationDocumentNotFound": "Bu döküman için menü bulunamadı!", "DocumentNotFoundInSelectedLanguage": "İstediğiniz dilde belge bulunamadı. Varsayılan dilde belge gösterilir.", + "FilterTopics": "Konuları Filtrele", + "FullSearch": "Dokümanlarda Ara", + "Volo.Docs.Domain:010001": "Elastic search etkin değil", "MultipleVersionDocumentInfo": "Bu dökümanın birden çok versiyonu bulunmaktadır. Sizin için en uygun olan seçenekleri seçiniz.", "New": "Yeni", "Upd": "Günc", "NewExplanation": "Son iki hafta içinde oluşturuldu.", - "UpdatedExplanation": "Son iki hafta içinde güncellendi." + "UpdatedExplanation": "Son iki hafta içinde güncellendi.", + "Volo.Docs.Domain:010002": "ShortName {ShortName} zaten var." } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml index 7f521de34b..90a754b1a9 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml @@ -131,10 +131,10 @@
@*
- -
*@ + +
*@ -
-
-
- } @if (Model.Navigation == null || !Model.Navigation.HasChildItems) { @@ -209,48 +190,60 @@ {
@@ -318,8 +311,20 @@
- +
+
@L["InThisDocument"]