@ -0,0 +1,14 @@ |
|||
{ |
|||
"culture": "de-DE", |
|||
"texts": { |
|||
"Account": "ABP Benutzerkonto - Anmeldung & Registrierung | ABP.IO", |
|||
"Welcome": "Willkommen", |
|||
"UseOneOfTheFollowingLinksToContinue": "Nutzen Sie einen der nachfolgenden Links um fortzusetzen", |
|||
"FrameworkHomePage": "Framework Website", |
|||
"FrameworkDocumentation": "Framework Dokumentation", |
|||
"OfficialBlog": "Offizieller Blog", |
|||
"CommercialHomePage": "Commercial Website", |
|||
"CommercialSupportWebSite": "Commercial Support-Website", |
|||
"CommunityWebSite": "ABP Community-Website" |
|||
} |
|||
} |
|||
@ -0,0 +1,199 @@ |
|||
{ |
|||
"culture": "de-DE", |
|||
"texts": { |
|||
"Permission:Organizations": "Organisationen", |
|||
"Permission:Manage": "Organisationen verwalten", |
|||
"Permission:DiscountRequests": "Rabattanfragen", |
|||
"Permission:DiscountManage": "Rabattanfragen verwalten", |
|||
"Permission:Disable": "Deaktivieren", |
|||
"Permission:Enable": "Aktivieren", |
|||
"Permission:EnableSendEmail": "E-Mail-Senden aktivieren", |
|||
"Permission:SendEmail": "E-Mail senden", |
|||
"Permission:NpmPackages": "NPM-Pakete", |
|||
"Permission:NugetPackages": "Nuget-Pakete", |
|||
"Permission:Maintenance": "Wartung", |
|||
"Permission:Maintain": "Warten", |
|||
"Permission:ClearCaches": "Caches leeren", |
|||
"Permission:Modules": "Module", |
|||
"Permission:Packages": "Pakete", |
|||
"Permission:Edit": "Bearbeiten", |
|||
"Permission:Delete": "Löschen", |
|||
"Permission:Create": "Erstellen", |
|||
"Permission:Accounting": "Abrechnung", |
|||
"Permission:Accounting:Quotation": "Angebot", |
|||
"Permission:Accounting:Invoice": "Rechnung", |
|||
"Menu:Organizations": "Organisationen", |
|||
"Menu:Accounting": "Abrechnung", |
|||
"Menu:Packages": "Pakete", |
|||
"Menu:DiscountRequests": "Rabattanfragen", |
|||
"NpmPackageDeletionWarningMessage": "Dieses NPM-Paket wird entfernt. Bestätigen Sie das?", |
|||
"NugetPackageDeletionWarningMessage": "Dieses Nuget-Paket wird entfernt. Bestägiten Sie das?", |
|||
"ModuleDeletionWarningMessage": "Dieses Modul wird entfernt. Bestätigen Sie das?", |
|||
"Name": "Name", |
|||
"DisplayName": "Anzeigename", |
|||
"ShortDescription": "Kurzbeschreibung", |
|||
"NameFilter": "Name", |
|||
"CreationTime": "Erstellungszeitpunkt", |
|||
"IsPro": "Ist pro", |
|||
"ShowOnModuleList": "In Modulliste anzeigen", |
|||
"EfCoreConfigureMethodName": "Methodenname konfigurieren", |
|||
"IsProFilter": "Ist pro", |
|||
"ApplicationType": "Anwendungstyp", |
|||
"Target": "Ziel", |
|||
"TargetFilter": "Ziel", |
|||
"ModuleClass": "Modulklasse", |
|||
"NugetPackageTarget.DomainShared": "Gemeinsame Domain", |
|||
"NugetPackageTarget.Domain": "Domain", |
|||
"NugetPackageTarget.Application": "Anwendung", |
|||
"NugetPackageTarget.ApplicationContracts": "Anwedungsverträge", |
|||
"NugetPackageTarget.HttpApi": "HTTP-API", |
|||
"NugetPackageTarget.HttpApiClient": "HTTP-API-Client", |
|||
"NugetPackageTarget.Web": "Web", |
|||
"NugetPackageTarget.EntityFrameworkCore": "DeleteAllEntityFramework Core", |
|||
"NugetPackageTarget.MongoDB": "MongoDB", |
|||
"Edit": "Bearbeiten", |
|||
"Delete": "Löschen", |
|||
"Refresh": "Aktualisieren", |
|||
"NpmPackages": "NPM-Pakete", |
|||
"NugetPackages": "Nuget-Pakete", |
|||
"NpmPackageCount": "NPM-Paketanzahl", |
|||
"NugetPackageCount": "Nuget-Paketanzahl", |
|||
"Module": "Module", |
|||
"ModuleInfo": "Modulinfo", |
|||
"CreateANpmPackage": "Erstellen Sie ein NPM Paket", |
|||
"CreateAModule": "Erstellen Sie in Modul", |
|||
"CreateANugetPackage": "Erstellen Sei ein Nuget-Paket", |
|||
"AddNew": "Neu hinzufügen", |
|||
"PackageAlreadyExist{0}": "\"{0}\" Paket ist bereits hinzugefügt.", |
|||
"ModuleAlreadyExist{0}": "\"{0}\" Modul ist bereits hinzugefügt.", |
|||
"ClearCache": "Cache leeren", |
|||
"SuccessfullyCleared": "Erfolgreich geleert", |
|||
"Menu:NpmPackages": "NPM-Pakete", |
|||
"Menu:Modules": "Module", |
|||
"Menu:Maintenance": "Wartung", |
|||
"Menu:NugetPackages": "Nuget-Pakete", |
|||
"CreateAnOrganization": "Erstellen Sie eine Organisation", |
|||
"Organizations": "Organisationen", |
|||
"LongName": "Lange Name", |
|||
"LicenseType": "Lizenztyp", |
|||
"MissingLicenseTypeField": "Das Feld Lizenztyp ist erforderlich!", |
|||
"LicenseStartTime": "Startzeit der Lizenz", |
|||
"LicenseEndTime": "Endzeit der Lizenz", |
|||
"AllowedDeveloperCount": "Zulässige Entwickleranzahl", |
|||
"UserNameOrEmailAddress": "Benutzername oder E-Mail-Adresse", |
|||
"AddOwner": "Besitzer hinzufügen", |
|||
"UserName": "Benutzername", |
|||
"Email": "E-Mail", |
|||
"Developers": "Entwickler", |
|||
"AddDeveloper": "Entwickler hinzufügen", |
|||
"Create": "Erstellen", |
|||
"UserNotFound": "Benutzer nicht gefunden", |
|||
"{0}WillBeRemovedFromDevelopers": "{0} wird von den Entwicklern entfernt. Bestätigen Sie das?", |
|||
"{0}WillBeRemovedFromOwners": "{0} wird von den Besitzern entfernt. Bestätigen Sie das?", |
|||
"Computers": "Computer", |
|||
"UniqueComputerId": "Eindeutig Computer-ID", |
|||
"LastSeenDate": "Zuletzt gesehenes Datum", |
|||
"{0}Computer{1}WillBeRemovedFromRecords": "Computer von {0} ({1}) wird aus den Datensätzen entfernt", |
|||
"OrganizationDeletionWarningMessage": "Organisation wird gelöscht", |
|||
"DeletingLastOwnerWarningMessage": "Eine Organisation muss zumindest einen Besitzer aufweisen! Daher können Sie diesen Besitzer nicht entfernen", |
|||
"This{0}AlreadyExistInThisOrganization": "Dies {0} existiert bereits in dieser Organisation", |
|||
"AreYouSureYouWantToDeleteAllComputers": "Sind Sie sicher, dass Sie alle Computer löschen möchten?", |
|||
"DeleteAll": "Alles Löschen", |
|||
"DoYouWantToCreateNewUser": "Möchten Sie einen neuen Benutzer erstellen?", |
|||
"MasterModules": "Master-Module", |
|||
"OrganizationName": "Organisationsname", |
|||
"CreationDate": "Erstellungsdatum", |
|||
"LicenseStartDate": "Startdatum der Lizenz", |
|||
"LicenseEndDate": "Enddatum der Lizenz", |
|||
"OrganizationNamePlaceholder": "Organisationsname...", |
|||
"TotalQuestionCountPlaceholder": "Gesamtzahl der Fragen...", |
|||
"RemainingQuestionCountPlaceholder": "Anzahl verbleibender Fragen...", |
|||
"LicenseTypePlaceholder": "Lizenztyp...", |
|||
"CreationDatePlaceholder": "Erstellungsdatum...", |
|||
"LicenseStartDatePlaceholder": "Startdatum der Lizenz...", |
|||
"LicenseEndDatePlaceholder": "Enddatum der Lizenz...", |
|||
"UsernameOrEmail": "Benutzername oder E-Mail-Adresse", |
|||
"UsernameOrEmailPlaceholder": "Benutzername oder E-Mail-Adresse...", |
|||
"Member": "Mitglied", |
|||
"PurchaseOrderNo": "Bestellnummer", |
|||
"QuotationDate": "Angebotsdatum", |
|||
"CompanyName": "Firmenname", |
|||
"CompanyAddress": "Firmenanschrift", |
|||
"Price": "Preis", |
|||
"DiscountText": "Rabatttext", |
|||
"DiscountQuantity": "Rabattmenge", |
|||
"DiscountPrice": "Rabattpreis", |
|||
"Quotation": "Angebot", |
|||
"ExtraText": "Zusätzlicher Text", |
|||
"ExtraAmount": "Zusätzliche Menge", |
|||
"DownloadQuotation": "Angebot herunterladen", |
|||
"Invoice": "Rechnung", |
|||
"TaxNumber": "Steuernummer", |
|||
"InvoiceNumber": "Rechnungsnummer", |
|||
"InvoiceDate": "Rechnungsdatum", |
|||
"InvoiceNote": "Rechnungsnotiz", |
|||
"Quantity": "Menge", |
|||
"AddProduct": "Produkt hinzufügen", |
|||
"AddProductWarning": "Sie müssen ein Produkt hinzufügen!", |
|||
"TotalPrice": "Gesamtpreis", |
|||
"Generate": "Generieren", |
|||
"MissingQuantityField": "Das Feld Menge ist erforderlich!", |
|||
"MissingPriceField": "Das Feld Preis ist erforderlich!", |
|||
"CodeUsageStatus": "Status", |
|||
"Country": "Land", |
|||
"DeveloperCount": "Entwickleranzahl", |
|||
"RequestCode": "Anfrage-Code", |
|||
"WebSite": "Webseite", |
|||
"GithubUsername": "Github Benutzername", |
|||
"PhoneNumber": "Telefonnummer", |
|||
"ProjectDescription": "Projektbeschreibung", |
|||
"Referrer": "Referrer", |
|||
"DiscountRequests": "Rabattanfrage", |
|||
"Copylink": "Link kopieren", |
|||
"Disable": "Deaktivieren", |
|||
"Enable": "Aktivieren", |
|||
"EnableSendEmail": "E-Mail-Senden aktivieren", |
|||
"SendEmail": "E-Mail senden", |
|||
"SuccessfullyDisabled": "Erfolgreich deaktiviert", |
|||
"SuccessfullyEnabled": "Erfolgreich aktiviert", |
|||
"EmailSent": "E-Mail gesendet", |
|||
"SuccessfullySent": "Erfolgreich gesendet", |
|||
"SuccessfullyDeleted": "Erfolgreich gelöscht", |
|||
"DiscountRequestDeletionWarningMessage": "Rabattanfrage wird gelöscht", |
|||
"BusinessType": "Unternehmensart", |
|||
"TotalQuestionCount": "Gesamtzahl der Fragen", |
|||
"RemainingQuestionCount": "Anzahl verbleibender Fragen", |
|||
"TotalQuestionMustBeGreaterWarningMessage": "TotalQuestionCount muss größer sein als RemainingQuestionCount !", |
|||
"QuestionCountsMustBeGreaterThanZero": "TotalQuestionCount und RemainingQuestionCount müssen Null oder größer als Null sein !", |
|||
"UnlimitedQuestionCount": "Unbegrenzte Anzahl von Fragen", |
|||
"Notes": "Anmerkungen", |
|||
"Menu:Community": "Community", |
|||
"Menu:Articles": "Beiträge", |
|||
"Wait": "Warten", |
|||
"Approve": "Genehmigen", |
|||
"Reject": "Ablehnen", |
|||
"Details": "Details", |
|||
"Url": "URL", |
|||
"Title": "Titel", |
|||
"ContentSource": "Inhaltsquelle", |
|||
"Status": "Status", |
|||
"ReadArticle": "Beitrag lesen", |
|||
"ArticleHasBeenWaiting": "Beitrag hat gewartet", |
|||
"ArticleHasBeenApproved": "Beitrag wurde genehmigt", |
|||
"ArticleHasBeenRejected": "Beitrag wurde abgelehnt", |
|||
"Permission:Community": "Community", |
|||
"Permission:CommunityArticle": "Beitrag", |
|||
"Link": "Link", |
|||
"Enum:ContentSource:0": "Github", |
|||
"Enum:ContentSource:1": "Extern", |
|||
"Enum:Status:0": "Wartend", |
|||
"Enum:Status:1": "Abgelehnt", |
|||
"Enum:Status:2": "Genehmigt", |
|||
"Summary": "Zusammenfassung", |
|||
"AuthorName": "Autorenname", |
|||
"CoverImage": "Titelbild", |
|||
"RemoveCacheConfirmationMessage": "Sind Sie sicher, dass Sie den Cache für den Artikel \"{0}\" entfernen wollen?", |
|||
"SuccessfullyRemoved": "Erfolgreich geleert", |
|||
"RemoveCache": "Cache entfernen" |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
{ |
|||
"culture": "de-DE", |
|||
"texts": { |
|||
"Volo.AbpIo.Domain:010004": "Maximale Mitgliederanzahl erreicht!", |
|||
"Volo.AbpIo.Domain:010005": "Miximale Besizeranzahl erreicht!", |
|||
"Volo.AbpIo.Domain:010006": "Dieser Benutzer ist bereits ein Besitzer in dieser Organisation!", |
|||
"Volo.AbpIo.Domain:010007": "Dieser Benutzer ist bereits ein Entwickler in dieser Organisation!", |
|||
"Volo.AbpIo.Domain:010008": "Die zulässige Entwickleranzahl darf nicht geringer sein als die aktuelle Entwickleranzahl!", |
|||
"Volo.AbpIo.Domain:010009": "Die zulässige Entwickleranzahl darf nicht kleiner als 0 sein!", |
|||
"Volo.AbpIo.Domain:010010": "Die maximale Anzahl der Mac-Adressen ist überschritten!", |
|||
"Volo.AbpIo.Domain:010011": "Die persönliche Lizenz kann nicht mehr als 1 Entwickler haben!", |
|||
"Volo.AbpIo.Domain:010012": "Die Lizenz kann nicht einen Monat nach Ablauf der Lizenz verlängert werden!", |
|||
"Volo.AbpIo.Domain:020001": "Dieses NPM-Paket konnte nicht gelöscht werden, da \"{NugetPackages}\" Nuget-Pakete von diesem Paket abhängig sind.", |
|||
"Volo.AbpIo.Domain:020002": "Dieses NPM-Paket konnte nicht gelöscht werden, da \"{Module}\" Module dieses Paket verwenden.", |
|||
"Volo.AbpIo.Domain:020003": "Dieses NPM-Paket konnte nicht gelöscht werden, da \"{Module}\" Module dieses Paket verwenden und \"{NugetPackages}\" Nuget-Pakete von diesem Paket abhängig sind.", |
|||
"Volo.AbpIo.Domain:020004": "Dieses Nuget-Paket konnte nicht gelöscht werden, da \"{Module}\" Module dieses Paket verwenden.", |
|||
"WantToLearn?": "Wollen Sie sich einlernen?", |
|||
"ReadyToGetStarted?": "Bereit anzufangen?", |
|||
"JoinOurCommunity": "Tritt unserer Community bei", |
|||
"GetStartedUpper": "LOSLEGEN", |
|||
"ForkMeOnGitHub": "Fork me on GitHub", |
|||
"Features": "Features", |
|||
"GetStarted": "Loslegen", |
|||
"Documents": "Unterlagen", |
|||
"Community": "Community", |
|||
"ContributionGuide": "Leitfaden für Mitwirkende", |
|||
"Blog": "Blog", |
|||
"Commercial": "Commercial", |
|||
"MyAccount": "Mein Benutzerkonto", |
|||
"SeeDocuments": "Siehe Unterlagen", |
|||
"Samples": "Beispiele" |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
{ |
|||
"culture": "de-DE", |
|||
"texts": { |
|||
"OrganizationManagement": "Organisationsverwaltung", |
|||
"OrganizationList": "Organisationsauflistung", |
|||
"Volo.AbpIo.Commercial:010003": "Sie sind der Besitzer dieser Organisation!", |
|||
"OrganizationNotFoundMessage": "Keine Organisation gefunden!", |
|||
"DeveloperCount": "Zugeordnete / Gesamte Entwickler", |
|||
"QuestionCount": "Verbleibende / Gesamte Fragen", |
|||
"Unlimited": "Unbegrenzt", |
|||
"Owners": "Besitzer", |
|||
"AddMember": "Mitglied hinzufügen", |
|||
"AddOwner": "Besizer hinzufügen", |
|||
"AddDeveloper": "Entwickler hinzufügen", |
|||
"UserName": "Benutzername", |
|||
"Name": "Name", |
|||
"EmailAddress": "E-Mail-Adress", |
|||
"Developers": "Entwickler", |
|||
"LicenseType": "Lizenztyp", |
|||
"Manage": "Verwalten", |
|||
"StartDate": "Startdatum", |
|||
"EndDate": "Enddatum", |
|||
"Modules": "Module", |
|||
"LicenseExtendMessage": "Ihr Lizenzenddatum wird auf {0} verlängert", |
|||
"LicenseUpgradeMessage": "Ihre Lizenz wird auf {0} aktualisiert", |
|||
"LicenseAddDeveloperMessage": "{0} Entwickler zu Ihrer Lizenz hinzugefügt", |
|||
"Volo.AbpIo.Commercial:010004": "Kann den angegebenen Benutzer nicht finden! Der Benutzer muss sich bereits registriert haben.", |
|||
"MyOrganizations": "Meine Organisationen", |
|||
"ApiKey": "API-Schlüssel", |
|||
"UserNameNotFound": "Es gibt keinen Benutzer mit dem Benutzernamen {0}", |
|||
"SuccessfullyAddedToNewsletter": "Vielen Dank, dass Sie unseren Newsletter abonniert haben!", |
|||
"MyProfile": "Mein Profil", |
|||
"EmailNotValid": "Bitte geben Sie eine gültige E-Mail-Adresse ein." |
|||
} |
|||
} |
|||
@ -0,0 +1,90 @@ |
|||
{ |
|||
"culture": "de-DE", |
|||
"texts": { |
|||
"Permission:CommunityArticle": "Community-Beitrag", |
|||
"Permission:Edit": "Bearbeiten", |
|||
"Waiting": "Wartend", |
|||
"Approved": "Genehmigt", |
|||
"Rejected": "Abgelehnt", |
|||
"Wait": "Warten", |
|||
"Approve": "Genehmigen", |
|||
"Reject": "Ablehnen", |
|||
"ReadArticle": "Beitrag lesen", |
|||
"Status": "Status", |
|||
"ContentSource": "Inhaltsquelle", |
|||
"Details": "Details", |
|||
"Url": "URL", |
|||
"Title": "Titel", |
|||
"CreationTime": "Erstellungszeitpunkt", |
|||
"Save": "Speichern", |
|||
"SameUrlAlreadyExist": "Dieselbe URL existiert bereits, wenn Sie diesen Beitrag hinzufügen möchten, sollten Sie die URL ändern!", |
|||
"UrlIsNotValid": "Der URL ist nicht korrekt.", |
|||
"UrlNotFound": "URL nicht gefunden.", |
|||
"UrlContentNotFound": "URL-Inhalt nicht gefunden", |
|||
"Summary": "Zusammenfassung", |
|||
"MostRead": "Meist gelesen", |
|||
"Latest": "Neueste", |
|||
"ContributeAbpCommunity": "Tragen Sie zur ABP Community bei", |
|||
"SubmitYourArticle": "Reichen Sie Ihren Beitrag ein", |
|||
"ContributionGuide": "Leitfaden für Mitwirkende", |
|||
"BugReport": "Fehler melden", |
|||
"SeeAllArticles": "Alle Beiträge anzeigen", |
|||
"WelcomeToABPCommunity!": "Willkommen in der ABP Community!", |
|||
"MyProfile": "Mein Profil", |
|||
"MyOrganizations": "Meine Organisationen", |
|||
"EmailNotValid": "Bitte geben Sie eine gültige E-Mail-Adresse ein.", |
|||
"FeatureRequest": "Featureanfrage", |
|||
"CreateArticleTitleInfo": "Titel des Beitrags, der in der Beitragsliste angezeigt werden soll.", |
|||
"CreateArticleUrlInfo": "Original GitHub-/externe URL des Beitrags.", |
|||
"CreateArticleSummaryInfo": "Eine kurze Zusammenfassung des Beitrags, der in der Beitragsliste angezeigt werden soll.", |
|||
"CreateArticleCoverInfo": "Fügen Sie zum Erstellen eines effektiven Beitrags ein Titelbild hinzu. Laden Sie Bilder mit einem Seitenverhältnis von 16: 9 hoch, um die beste Ansicht zu erhalten.", |
|||
"ThisExtensionIsNotAllowed": "Diese Erweiterung ist nicht zulässig.", |
|||
"TheFileIsTooLarge": "Die Datei ist zu groß.", |
|||
"GoToTheArticle": "Gehe zum Beitrag", |
|||
"Contribute": "Beitragen", |
|||
"OverallProgress": "Gesamtfortschritt", |
|||
"Done": "Ferig", |
|||
"Open": "Offen", |
|||
"Closed": "Geschlossen", |
|||
"LatestQuestionOnThe": "Letzte Frage zum", |
|||
"Stackoverflow": "Stackoverflow", |
|||
"Votes": "Stimmen", |
|||
"Answer": "Antworten", |
|||
"Views": "Ansichten", |
|||
"Answered": "Beantwortet", |
|||
"WaitingForYourAnswer": "Warten auf Ihre Antwort", |
|||
"Asked": "gefragt", |
|||
"AllQuestions": "Alle Fragen", |
|||
"NextVersion": "Nächste Version", |
|||
"MilestoneErrorMessage": "Die aktuellen Meilensteindetails konnten von Github nicht abgerufen werden.", |
|||
"QuestionItemErrorMessage": "Die neuesten Fragendetails konnten von Stackoverflow nicht abgerufen werden.", |
|||
"Oops": "Hoppla!", |
|||
"CreateArticleSuccessMessage": "Der Beitrag wurde erfolgreich eingereicht. Er wird nach einer Überprüfung durch den Site-Administrator veröffentlicht.", |
|||
"ChooseCoverImage": "Wählen Sie ein Titelbild ...", |
|||
"CoverImage": "Titelbild", |
|||
"ShareYourExperiencesWithTheABPFramework": "Teilen Sie Ihre Erfahrungen mit dem ABP Framework!", |
|||
"Optional": "Optional", |
|||
"UpdateUserWebSiteInfo": "Beispiel: https://johndoe.com", |
|||
"UpdateUserTwitterInfo": "Beispiel: johndoe", |
|||
"UpdateUserGithubInfo": "Beispiel: johndoe", |
|||
"UpdateUserLinkedinInfo": "Beispiel: https://www.linkedin.com/...", |
|||
"UpdateUserCompanyInfo": "Beispiel: Volosoft", |
|||
"UpdateUserJobTitleInfo": "Beispiel: Software Developer", |
|||
"UserName": "Benutzername", |
|||
"Company": "Firma", |
|||
"PersonalWebsite": "Persönliche Website", |
|||
"RegistrationDate": "Registrierungsdatum", |
|||
"Social": "Social", |
|||
"Biography": "Biographie", |
|||
"HasNoPublishedArticlesYet": "hat noch keine Beiträge veröffentlicht", |
|||
"Author": "Autor", |
|||
"LatestGithubAnnouncements": "Neueste Github-Ankündigungen", |
|||
"SeeAllAnnouncements": "Alle Ankündigungen anzeigen", |
|||
"LatestBlogPost": "Letzter Blog-Beitrag", |
|||
"Edit": "Bearbeiten", |
|||
"ProfileImageChange": "Ändern Sie das Profilbild", |
|||
"BlogItemErrorMessage": "Die neuesten Blogpost-Details konnten von ABP nicht abgerufen werden.", |
|||
"PlannedReleaseDate": "Geplantes Erscheinungsdatum", |
|||
"CommunityArticleRequestErrorMessage": "Die Anfrage nach den neuesten Beiträgen von Github konnte nicht abgerufen werden." |
|||
} |
|||
} |
|||
@ -0,0 +1,189 @@ |
|||
{ |
|||
"culture": "de-DE", |
|||
"texts": { |
|||
"GetStarted": "Erste Schritte - Startvorlagen", |
|||
"Create": "Erstellen", |
|||
"NewProject": "Neues Projekt", |
|||
"DirectDownload": "Direkter Download", |
|||
"ProjectName": "Proejktname", |
|||
"ProjectType": "Projekttyp", |
|||
"DatabaseProvider": "Datenbankanbieter", |
|||
"NTier": "N-Tier", |
|||
"IncludeUserInterface": "Benutzeroberfläche einschließen", |
|||
"CreateNow": "Jetzt erstellen", |
|||
"TheStartupProject": "Das Startprojekt", |
|||
"Tutorial": "Lernprogramm", |
|||
"UsingCLI": "mit CLI", |
|||
"SeeDetails": "Details ansehen", |
|||
"AbpShortDescription": "ABP Framework ist eine vollständige Infrastruktur zum Erstellen moderner Webanwendungen unter Befolgung von Best Practices und Konventionen für Softwareentwicklung.", |
|||
"SourceCodeUpper": "QUELLCODE", |
|||
"LatestReleaseLogs": "Akteulle Release", |
|||
"Infrastructure": "Infrastrutkur", |
|||
"Architecture": "Architektur", |
|||
"Modular": "Modular", |
|||
"DontRepeatYourself": "Don't Repeat Yourself", |
|||
"DeveloperFocused": "Entwickler-Zentriert", |
|||
"FullStackApplicationInfrastructure": "Full-Stack-Anwendungsinfrastruktur.", |
|||
"DomainDrivenDesign": "Domain Driven Design", |
|||
"DomainDrivenDesignExplanation": "Entworfen und entwickelt basierend auf DDD-Mustern und -Prinzipien. Bietet ein Schichtenmodell für Ihre Anwendung.", |
|||
"Authorization": "Authorization", |
|||
"AuthorizationExplanation": "Erweiterte Autorisierung mit Benutzer-, Rollen- und fein abgestimmtem Berechtigungssystem. Aufbauend auf der Microsoft Identity-Bibliothek.", |
|||
"MultiTenancy": "Multi-Tenancy", |
|||
"MultiTenancyExplanationShort": "SaaS-Anwendungen leicht gemacht! Integrierte Mandantenfähigkeit von der Datenbank bis zur Benutzeroberfläche.", |
|||
"CrossCuttingConcerns": "Cross Cutting Concerns", |
|||
"CrossCuttingConcernsExplanationShort": "Komplette Infrastruktur für Autorisierung, Validierung, Ausnahmebehandlung, Caching, Überwachungsprotokollierung, Transaktionsverwaltung und mehr.", |
|||
"BuiltInBundlingMinification": "Built-In Bundling & Minification", |
|||
"BuiltInBundlingMinificationExplanation": "Für die Bundling und Minification müssen keine externen Tools verwendet werden. ABP bietet eine einfachere, dynamische, leistungsstarke, modulare und integrierte Methode!", |
|||
"VirtualFileSystem": "Virtual File System", |
|||
"VirtualFileSystemExplanation": "Betten Sie Ansichten, Skripte, Stile, Bilder ... in Pakete/Bibliotheken ein und verwenden Sie sie in verschiedenen Anwendungen wieder.", |
|||
"Theming": "Theming", |
|||
"ThemingExplanationShort": "Verwenden und passen Sie das Bootstrap-basierte Standard-UI-Design an oder erstellen Sie Ihr eigenes.", |
|||
"BootstrapTagHelpersDynamicForms": "Bootstrap Tag Helpers & Dynamic Forms", |
|||
"BootstrapTagHelpersDynamicFormsExplanation": "Anstatt die sich wiederholenden Details von Bootstrap-Komponenten manuell zu schreiben, verwenden Sie die Tag-Helper von ABP, um diese zu vereinfachen und dabei die Vorteile von Intellisense zu nutzen. Erstellen Sie mit dem dynamischen Formular-Tag-Helfer schnell UI-Formulare basierend auf einem C#-Modell.", |
|||
"HTTPAPIsDynamicProxies": "HTTP APIs & Dynamic Proxies", |
|||
"HTTPAPIsDynamicProxiesExplanation": "Stellen Sie Anwendungsdienste automatisch als HTTP-APIs im REST-Stil bereit und verwenden Sie diese mit dynamischen JavaScript- und C#-Proxys.", |
|||
"CompleteArchitectureInfo": "Moderne Architektur zur Erstellung wartbarer Softwarelösungen.", |
|||
"DomainDrivenDesignBasedLayeringModelExplanation": "Hilft Ihnen bei der Implementierung einer DDD-basierten Schichtarchitektur und beim Aufbau einer wartbaren Codebasis.", |
|||
"DomainDrivenDesignBasedLayeringModelExplanationCont": "Bietet Startvorlagen, Abstraktionen, Basisklassen, Dienste, Dokumentation und Anleitungen, mit denen Sie Ihre Anwendung basierend auf DDD-Mustern und -Prinzipien entwickeln können.", |
|||
"MicroserviceCompatibleModelExplanation": "Das Kernframework und die vorgefertigten Module sind unter Berücksichtigung der Microservice-Architektur konzipiert.", |
|||
"MicroserviceCompatibleModelExplanationCont": "Bietet Infrastruktur, Integrationen, Beispiele und Dokumentation zur einfacheren Implementierung von Microservice-Lösungen, ohne zusätzliche Komplexität zu verursachen, wenn Sie eine monolithische Anwendung wünschen.", |
|||
"ModularInfo": "ABP bietet ein Modulsystem, mit dem Sie wiederverwendbare Anwendungsmodule entwickeln, Ereignisse im Anwendungslebenszyklus verknüpfen und Abhängigkeiten zwischen Kernteilen Ihres Systems ausdrücken können.", |
|||
"PreBuiltModulesThemes": "Vorgefertigte Module & Themes", |
|||
"PreBuiltModulesThemesExplanation": "Open Source- und kommerzielle Module und Themes stehen bereit, um in Ihrer Geschäftsanwendung verwendet zu werden.", |
|||
"NuGetNPMPackages": "NuGet- & NPM-Pakete", |
|||
"NuGetNPMPackagesExplanation": "Bereitgestellt als NuGet- & NPM-Pakete. Einfach zu installieren und zu aktualisieren.", |
|||
"ExtensibleReplaceable": "Erweiterbar/Austauschbar", |
|||
"ExtensibleReplaceableExplanation": "Alle Dienste und Module sind auf Erweiterbarkeit ausgelegt. Sie können Dienste, Seiten, Stile und Komponenten ersetzen.", |
|||
"CrossCuttingConcernsExplanation2": "Halten Sie Ihre Codebasis kleiner, damit Sie sich auf ihre geschäftsspezifischen Code konzentrieren können.", |
|||
"CrossCuttingConcernsExplanation3": "Verbringen Sie keine Zeit damit, grundlegende Anwendungsanforderungen für jedes neue Projekte zu implementieren.", |
|||
"AuthenticationAuthorization": "Authentifizierung & Autorisierung", |
|||
"ExceptionHandling": "Fehlerbehandlung", |
|||
"Validation": "Validierung", |
|||
"DatabaseConnection": "Datenbankverbindung", |
|||
"TransactionManagement": "Transaktionsmanagement", |
|||
"AuditLogging": "Audit Logging", |
|||
"Caching": "Caching", |
|||
"Multitenancy": "Multimandantenfähigkeit", |
|||
"DataFiltering": "Datenfilterung", |
|||
"ConventionOverConfiguration": "Convention Over Configuration", |
|||
"ConventionOverConfigurationExplanation": "ABP implementiert standardmäßig allgemeine Anwendungskonventionen mit einer minimalen oder Null-Konfiguration.", |
|||
"ConventionOverConfigurationExplanationList1": "Automatische Registrierung bekannter Services für Dependency Injection.", |
|||
"ConventionOverConfigurationExplanationList2": "Stellt Anwendungsdienste mittels Namenskonventionen als HTTP-APIs bereit.", |
|||
"ConventionOverConfigurationExplanationList3": "Erstellt dynamische HTTP-Client-Proxys für C# und JavaScript.", |
|||
"ConventionOverConfigurationExplanationList4": "Bietet Standard-Repositorys für Ihre Entities.", |
|||
"ConventionOverConfigurationExplanationList5": "Verwaltet die Unit-of-Work gemäß Webanforderung oder Anwendungsdienstmethode.", |
|||
"ConventionOverConfigurationExplanationList6": "Triggert Erstellungs-, Aktualisierungs- und Lösch-Events für Ihre Entities.", |
|||
"BaseClasses": "Basisklassen", |
|||
"BaseClassesExplanation": "Vorgefertigte Basisklassen für gängige Anwendungsmuster.", |
|||
"DeveloperFocusedExplanation": "ABP ist für Entwickler", |
|||
"DeveloperFocusedExplanationCont": "Es zielt darauf ab, Ihre tägliche Softwareentwicklung zu vereinfachen, ohne Sie daran zu hindern, Low-Level-Code zu schreiben.", |
|||
"SeeAllFeatures": "Alle Features anzeigen", |
|||
"CLI_CommandLineInterface": "CLI (Command Line Interface)", |
|||
"CLI_CommandLineInterfaceExplanation": "Enthält eine CLI, mit der Sie die Erstellung neuer Projekte und das Hinzufügen neuer Module automatisieren können.", |
|||
"StartupTemplates": "Startvorlagen", |
|||
"StartupTemplatesExplanation": "Verschiedene Startvorlagen bieten eine vollständig konfigurierte Lösung, um Ihre Entwicklung zu beschleunigen.", |
|||
"BasedOnFamiliarTools": "Basierend auf vertrauten Tools", |
|||
"BasedOnFamiliarToolsExplanation": "Aufbauend auf und integriert mit beliebten Tools, die Sie bereits kennen. Geringe Lernkurve, einfache Anpassung, komfortable Entwicklung.", |
|||
"ORMIndependent": "ORM-unabhängig", |
|||
"ORMIndependentExplanation": "Das Kernframework ist ORM-/datenbankunabhängig und kann mit jeder Datenquelle arbeiten. Entity Framework Core- und MongoDB-Anbieter sind bereits verfügbar.", |
|||
"Features": "Entdecken Sie die ABP Framework-Features", |
|||
"ABPCLI": "ABP CLI", |
|||
"Modularity": "Modularität", |
|||
"BootstrapTagHelpers": "Bootstrap Tag Helpers", |
|||
"DynamicForms": "Dynamische Formulare", |
|||
"BundlingMinification": "Bundling & Minification", |
|||
"BackgroundJobs": "Background Jobs", |
|||
"BackgroundJobsExplanation": "Definieren Sie einfache Klassen, um Jobs im Hintergrund in der Warteschlange auszuführen. Verwenden Sie den integrierten Jobmanager oder integrieren Sie Ihren eigenen. <a href=\"{0}\"> Hangfire </a> & <a href=\"{1}\"> RabbitMQ </a> -Integrationen sind bereits verfügbar.", |
|||
"DDDInfrastructure": "DDD-Infrastruktur", |
|||
"DomainDrivenDesignInfrastructure": "Domain Driven Design-Infrastruktur", |
|||
"AutoRESTAPIs": "Auto REST APIs", |
|||
"DynamicClientProxies": "Dynamische Client-Proxies", |
|||
"DistributedEventBus": "Distributed Event Bus", |
|||
"DistributedEventBusWithRabbitMQIntegration": "Distributed Event Bus mit RabbitMQ-Integration", |
|||
"TestInfrastructure": "Test-Infrastruktur", |
|||
"AuditLoggingEntityHistories": "Audit Logging & Entity Histories", |
|||
"ObjectToObjectMapping": "Object to Object Mapping", |
|||
"ObjectToObjectMappingExplanation": "<a href=\"{0}\"> Object to Object Mapping </a> Abstraktion mit AutoMapper-Integration.", |
|||
"EmailSMSAbstractions": "E-Mail & SMS Abstraktionen", |
|||
"EmailSMSAbstractionsWithTemplatingSupport": "E-Mail- und SMS-Abstraktionen mit Vorlagenunterstützung", |
|||
"Localization": "Lokalisierung", |
|||
"SettingManagement": "Einstellungsverwaltung", |
|||
"ExtensionMethods": "Erweiterungsmethoden", |
|||
"ExtensionMethodsHelpers": "Erweiterungsmethoden & Helfer", |
|||
"AspectOrientedProgramming": "Aspektorientierte Programmierung", |
|||
"DependencyInjection": "Dependency Injection", |
|||
"DependencyInjectionByConventions": "Dependency Injection durch Konventionen", |
|||
"ABPCLIExplanation": "ABP CLI (Command Line Interface) ist ein Befehlszeilenprogramm zum Ausführen einiger gängiger Vorgänge für ABP-basierte Lösungen.", |
|||
"ModularityExplanation": "ABP bietet eine vollständige Infrastruktur zum Erstellen eigener Anwendungsmodule, die Entities, Services, Datenbankintegration, APIs, UI-Komponenten usw. enthalten können.", |
|||
"MultiTenancyExplanation": "Das ABP-Framework unterstützt nicht nur die Entwicklung von Multi-Mandantenanwendungen, sondern macht Ihren Code von der Mandantenfähigkeit auch weitgehend unabhängig.", |
|||
"MultiTenancyExplanation2": "Kann den aktuellen Mandanten automatisch ermitteln und Daten verschiedener Mandanten voneinander isolieren.", |
|||
"MultiTenancyExplanation3": "Unterstützt einzelne Datenbank-, Datenbank-pro-Mandanten- und Hybrid-Ansätze.", |
|||
"MultiTenancyExplanation4": "Sie konzentrieren sich auf Ihren geschäftsspezifischen Code und lassen das Framework die Mandantenfähigkeit für Sie übernehmen.", |
|||
"BootstrapTagHelpersExplanation": "Anstatt die sich wiederholenden Details von Bootstrap-Komponenten manuell zu schreiben, verwenden Sie die Tag-Helper von ABP, um diese zu vereinfachen und dabei die Vorteile von Intellisense zu nutzen. Sie können Bootstrap weitherhin verwenden, wann immer Sie es benötigen.", |
|||
"DynamicFormsExplanation": "Helfer für dynamische Formular- und Input-Tags können das vollständige Formular anhand einer C#-Klasse als Model erstellen.", |
|||
"AuthenticationAuthorizationExplanation": "Umfangreiche Authentifizierungs- und Autorisierungsoptionen, die in ASP.NET Core Identity & IdentityServer4 integriert sind. Bietet ein erweiterbares und detailliertes Berechtigungssystem.", |
|||
"CrossCuttingConcernsExplanation": "Wiederholen Sie sich nicht, um all diese allgemeinen Dinge immer wieder zu implementieren. Konzentrieren Sie sich auf Ihren geschäftsspezifischen Code und lassen Sie ihn von ABP durch Konventionen automatisieren.", |
|||
"DatabaseConnectionTransactionManagement": "Datenbankverbindungs- und Transaktionsmanagement", |
|||
"CorrelationIdTracking": "Correlation-ID-Verfolgung", |
|||
"BundlingMinificationExplanation": "ABP bietet ein einfaches, dynamisches, leistungsstarkes, modulares und integriertes Bundling- und Minification-System.", |
|||
"VirtualFileSystemnExplanation": "Das virtuelle Dateisystem ermöglicht die Verwaltung von Dateien, die physisch nicht auf dem Dateisystem (Datenträger) vorhanden sind. Es wird hauptsächlich verwendet, um Dateien (js, css, image, cshtml ...) in Assemblys einzubetten und sie zur Laufzeit wie physische Dateien zu verwenden.", |
|||
"ThemingExplanation": "Mit dem Theming-System können Sie Ihre Anwendung & Module Theme-unabhängig entwickeln, indem Sie eine Reihe gemeinsamer Basisbibliotheken und Layouts definieren, die auf dem neuesten Bootstrap-Framework basieren.", |
|||
"DomainDrivenDesignInfrastructureExplanation": "Eine vollständige Infrastruktur zum Erstellen von mehrschichtigen Anwendungen basierend auf den Domain Driven Design Entwurfsmustern und -prinzipien;", |
|||
"Specification": "Specification", |
|||
"Repository": "Repository", |
|||
"DomainService": "Domain Service", |
|||
"ValueObject": "Value Object", |
|||
"ApplicationService": "Application Service", |
|||
"DataTransferObject": "Data Transfer Object", |
|||
"AggregateRootEntity": "Aggregate Root, Entity", |
|||
"AutoRESTAPIsExplanation": "ABP kann Ihre Anwendungsservices gemäß Konvention automatisch als API-Controller konfigurieren.", |
|||
"DynamicClientProxiesExplanation": "Verwenden Sie Ihre APIs ganz einfach in JavaScript- und C#-Clients.", |
|||
"DistributedEventBusWithRabbitMQIntegrationExplanation": "Veröffentlichen und konsumieren Sie Distributed Events einfach mithilfe des integrierten Distributed Event Bus mit verfügbarer RabbitMQ-Integration.", |
|||
"TestInfrastructureExplanation": "Das Framework wurde unter Berücksichtigung von Unit- und Integrationstests entwickelt. Bietet Ihnen Basisklassen, um es einfacher zu machen. Startvorlagen werden mit vorkonfiguriert Tests geliefert.", |
|||
"AuditLoggingEntityHistoriesExplanation": "Integriertes Audit Logging für geschäftskritische Anwendungen. Audit Logging auf Request-, Service-, und Methodenebene sowie Entity-Historien mit Details auf Property-Ebene.", |
|||
"EmailSMSAbstractionsWithTemplatingSupportExplanation": "IEmailSender- und ISmsSender-Abstraktionen entkoppeln Ihre Anwendungslogik von der Infrastruktur. Das erweiterte E-Mail-Vorlagensystem ermöglicht das Erstellen und Lokalisieren von E-Mail-Vorlagen und deren einfache Verwendung bei Bedarf.", |
|||
"LocalizationExplanation": "Das Lokalisierungssystem ermöglicht das Erstellen von Ressourcen in einfachen JSON-Dateien und die Lokalisierung Ihrer Benutzeroberfläche. Es unterstützt erweiterte Szenarien wie Vererbung, Erweiterungen und JavaScript-Integration und ist vollständig mit dem Lokalisierungssystem von AspNet Core kompatibel.", |
|||
"SettingManagementExplanation": "Definieren Sie Einstellungen für Ihre Anwendung und erhalten Sie zur Laufzeit Werte basierend auf der aktuellen Konfiguration, dem Mandanten und dem Benutzer.", |
|||
"ExtensionMethodsHelpersExplanation": "Wiederholen Sie sich nicht einmal für triviale Codeteile. Erweiterungen und Helfer für Standardtypen machen Ihren Code viel sauberer und einfacher zu schreiben.", |
|||
"AspectOrientedProgrammingExplanation": "Bietet eine komfortable Infrastruktur zum Erstellen dynamischer Proxys und zum Implementieren der aspektorientierten Programmierung. Fangen Sie eine Klasse ab und führen Sie Ihren Code vor und nach jeder Methodenausführung aus.", |
|||
"DependencyInjectionByConventionsExplanation": "Sie müssen Ihre Klassen nicht manuell für die Dependency Injection registrieren. Registriert gängige Servicetypen automatisch gemäß Konvention. Für andere Arten von Services können Sie Schnittstellen und Attribute verwenden, um dies einfacher gestalten und an Ort und Stelle zu ermöglichen.", |
|||
"DataFilteringExplanation": "Definieren und verwenden Sie Datenfilter, die automatisch angewendet werden, wenn Sie Entities aus der Datenbank abfragen. Soft Delete- und Multimandanten-Filter sind sofort verfügbar, wenn Sie einfache Schnittstellen implementieren.", |
|||
"PublishEvents": "Events veröffentlichen", |
|||
"HandleEvents": "Auf Events reagieren", |
|||
"AndMore": "und mehr...", |
|||
"Code": "Code", |
|||
"Result": "Resultat", |
|||
"SeeTheDocumentForMoreInformation": "Weitere Informationen finden Sie in der <a href=\"{1}\"> {0} -Dokumentation </a>", |
|||
"IndexPageHeroSection": "<span class=\"first-line shine\"><strong>Open Source</strong></span><span class=\"second-line text-uppercase\">Webanwendung<br />Framework </span><span class=\"third-line shine2\"><strong>für ASP.Net Core</strong></span>", |
|||
"UiFramework": "UI-Framework", |
|||
"EmailAddress": "E-Mail-Adresse", |
|||
"Mobile": "Mobile", |
|||
"ReactNative": "React Native", |
|||
"Strong": "Stark", |
|||
"Complete": "Vollständig", |
|||
"BasedLayeringModel": "Based Layering Model", |
|||
"Microservice": "Microservice", |
|||
"Compatible": "Kompatibel", |
|||
"MeeTTheABPCommunityInfo": "Unsere Mission ist es, eine Umgebung zu schaffen, in der Entwickler sich gegenseitig mit Beiträgen, Tutorials, Fallstudien usw. helfen und Gleichgesinnte treffen können.", |
|||
"JoinTheABPCommunityInfo": "Beteiligen Sie sich an einer lebendigen Community und tragen Sie zum ABP Framework bei!", |
|||
"AllArticles": "Alle Beiträge", |
|||
"SubmitYourArticle": "Reichen Sie Ihren Beitrag ein", |
|||
"DynamicClientProxyDocument": "In der Dokumentation zu den Dynamischen Client-Proxies finden Sie Informationen zu <a href=\"{0}\">JavaScript</a> & <a href=\"{1}\">C#</a>.", |
|||
"EmailSMSAbstractionsDocument": "Weitere Informationen finden Sie in den Unterlagen <a href=\"{0}\">E-Mail-Senden</a> and <a href=\"{1}\">SMS-Senden</a>.", |
|||
"CreateProjectWizard": "Dieser Assistent erstellt ein neues Projekt aus der Startvorlage, die ordnungsgemäß konfiguriert ist, um Ihr Projekt zu starten.", |
|||
"TieredOption": "Erstellt eine Tiered Lösung, bei der Web- und HTTP-API-Ebenen physisch getrennt sind. Wenn diese Option nicht aktiviert ist, wird eine mehrschichtige Lösung erstellt, die weniger komplex und für die meisten Szenarien geeignet ist.", |
|||
"SeparateIdentityServerOption": "Trennt die Serverseite in zwei Anwendungen: Die erste ist für den Identitätsserver und die zweite für die serverseitige HTTP-API.", |
|||
"UseslatestPreVersion": "Verwendet die neueste Vorabversion", |
|||
"ReadTheDocumentation": "<span class=\"text-primary\">Lesen Sie</span><span class=\"text-success\">Die Dokumentation</span>", |
|||
"Documentation": "Dokumentation", |
|||
"GettingStartedTutorial": "Erste Schritte Tutorial", |
|||
"ApplicationDevelopmentTutorial": "Tutorial zur Anwendungsentwicklung", |
|||
"TheStartupTemplate": "Die Startvorlage", |
|||
"InstallABPCLIInfo": "ABP CLI ist der schnellste Weg, um eine neue Lösung mit dem ABP-Framework zu starten. Installieren Sie die ABP-CLI über die Eingabeaufforderung:", |
|||
"DifferentLevelOfNamespaces": "Sie können verschiedene Ebenen von Namespaces verwenden; z.B. BookStore, Acme.BookStore or Acme.Retail.BookStore.", |
|||
"ABPCLIExamplesInfo": "Der Befehl <strong>new</strong> erstellt eine <strong>mehrschichtige MVC-Anwendung</strong> mit <strong>Entity Framework Core</strong> als Datenbankanbieter. Es gibt jedoch zusätzliche Optionen. Beispiele:", |
|||
"SeeCliDocumentForMoreInformation": "Weitere Optionen finden Sie im <a href=\"{0}\">ABP CLI-Dokument</a> oder wählen Sie oben die Registerkarte \"Direkter Download\".", |
|||
"Optional": "Optional", |
|||
"LocalFrameworkRef": "Behalten Sie die lokale Projektreferenz für die Framework-Pakete bei." |
|||
} |
|||
} |
|||
@ -1,3 +1,135 @@ |
|||
# Domain Services |
|||
|
|||
TODO |
|||
## Introduction |
|||
|
|||
In a [Domain Driven Design](Domain-Driven-Design.md) (DDD) solution, the core business logic is generally implemented in aggregates ([entities](Entities.md)) and the Domain Services. Creating a Domain Service is especially needed when; |
|||
|
|||
* You implement a core domain logic that depends on some services (like repositories or other external services). |
|||
* The logic you need to implement is related to more than one aggregate/entity, so it doesn't properly fit in any of the aggregates. |
|||
|
|||
## ABP Domain Service Infrastructure |
|||
|
|||
Domain Services are simple, stateless classes. While you don't have to derive from any service or interface, ABP Framework provides some useful base classes and conventions. |
|||
|
|||
### DomainService & IDomainService |
|||
|
|||
Either derive a Domain Service from the `DomainService` base class or directly implement the `IDomainService` interface. |
|||
|
|||
**Example: Create a Domain Service deriving from the `DomainService` base class.** |
|||
|
|||
````csharp |
|||
using Volo.Abp.Domain.Services; |
|||
|
|||
namespace MyProject.Issues |
|||
{ |
|||
public class IssueManager : DomainService |
|||
{ |
|||
|
|||
} |
|||
} |
|||
```` |
|||
|
|||
When you do that; |
|||
|
|||
* ABP Framework automatically registers the class to the Dependency Injection system with a Transient lifetime. |
|||
* You can directly use some common services as base properties, without needing to manually inject (e.g. [ILogger](Logging.md) and [IGuidGenerator](Guid-Generation.md)). |
|||
|
|||
> It is suggested to name a Domain Service with a `Manager` or `Service` suffix. We typically use the `Manager` suffix as used in the sample above. |
|||
|
|||
**Example: Implement the domain logic of assigning an Issue to a User** |
|||
|
|||
````csharp |
|||
public class IssueManager : DomainService |
|||
{ |
|||
private readonly IRepository<Issue, Guid> _issueRepository; |
|||
|
|||
public IssueManager(IRepository<Issue, Guid> issueRepository) |
|||
{ |
|||
_issueRepository = issueRepository; |
|||
} |
|||
|
|||
public async Task AssignAsync(Issue issue, AppUser user) |
|||
{ |
|||
var currentIssueCount = await _issueRepository |
|||
.CountAsync(i => i.AssignedUserId == user.Id); |
|||
|
|||
//Implementing a core business validation |
|||
if (currentIssueCount >= 3) |
|||
{ |
|||
throw new IssueAssignmentException(user.UserName); |
|||
} |
|||
|
|||
issue.AssignedUserId = user.Id; |
|||
} |
|||
} |
|||
```` |
|||
|
|||
Issue is an [aggregate root](Entities.md) defined as shown below: |
|||
|
|||
````csharp |
|||
public class Issue : AggregateRoot<Guid> |
|||
{ |
|||
public Guid? AssignedUserId { get; internal set; } |
|||
|
|||
//... |
|||
} |
|||
```` |
|||
|
|||
* Making the setter `internal` ensures that it can not directly set in the upper layers and forces to always use the `IssueManager` to assign an `Issue` to a `User`. |
|||
|
|||
### Using a Domain Service |
|||
|
|||
A Domain Service is typically used in an [application service](Application-Services.md). |
|||
|
|||
**Example: Use the `IssueManager` to assign an Issue to a User** |
|||
|
|||
````csharp |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using MyProject.Users; |
|||
using Volo.Abp.Application.Services; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace MyProject.Issues |
|||
{ |
|||
public class IssueAppService : ApplicationService, IIssueAppService |
|||
{ |
|||
private readonly IssueManager _issueManager; |
|||
private readonly IRepository<AppUser, Guid> _userRepository; |
|||
private readonly IRepository<Issue, Guid> _issueRepository; |
|||
|
|||
public IssueAppService( |
|||
IssueManager issueManager, |
|||
IRepository<AppUser, Guid> userRepository, |
|||
IRepository<Issue, Guid> issueRepository) |
|||
{ |
|||
_issueManager = issueManager; |
|||
_userRepository = userRepository; |
|||
_issueRepository = issueRepository; |
|||
} |
|||
|
|||
public async Task AssignAsync(Guid id, Guid userId) |
|||
{ |
|||
var issue = await _issueRepository.GetAsync(id); |
|||
var user = await _userRepository.GetAsync(userId); |
|||
|
|||
await _issueManager.AssignAsync(issue, user); |
|||
await _issueRepository.UpdateAsync(issue); |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
Since the `IssueAppService` is in the Application Layer, it can't directly assign an issue to a user. So, it uses the `IssueManager`. |
|||
|
|||
## Application Services vs Domain Services |
|||
|
|||
While both of [Application Services](Application-Services.md) and Domain Services implement the business rules, there are fundamental logical and formal differences; |
|||
|
|||
* Application Services implement the **use cases** of the application (user interactions in a typical web application), while Domain Services implement the **core, use case independent domain logic**. |
|||
* Application Services get/return [Data Transfer Objects](Data-Transfer-Objects.md), Domain Service methods typically get and return the **domain objects** ([entities](Entities.md), [value objects](Value-Objects.md)). |
|||
* Domain services are typically used by the Application Services or other Domain Services, while Application Services are used by the Presentation Layer or Client Applications. |
|||
|
|||
## Lifetime |
|||
|
|||
Lifetime of Domain Services are [transient](https://docs.abp.io/en/abp/latest/Dependency-Injection) and they are automatically registered to the dependency injection system. |
|||
@ -1,3 +1,255 @@ |
|||
# Specifications |
|||
|
|||
TODO! |
|||
Specification Pattern is used to define **named, reusable, combinable and testable filters** for entities and other business objects. |
|||
|
|||
> A Specification is a part of the Domain Layer. |
|||
|
|||
## Installation |
|||
|
|||
> This package is **already installed** when you use the startup templates. So, most of the times you don't need to manually install it. |
|||
|
|||
Install the [Volo.Abp.Specifications](https://abp.io/package-detail/Volo.Abp.Specifications) package to your project. You can use the [ABP CLI](CLI.md) *add-package* command in a command line terminal when the current folder is the root folder of your project (`.csproj`): |
|||
|
|||
````bash |
|||
abp add-package Volo.Abp.Specifications |
|||
```` |
|||
|
|||
## Defining the Specifications |
|||
|
|||
Assume that you've a Customer entity as defined below: |
|||
|
|||
````csharp |
|||
using System; |
|||
using Volo.Abp.Domain.Entities; |
|||
|
|||
namespace MyProject |
|||
{ |
|||
public class Customer : AggregateRoot<Guid> |
|||
{ |
|||
public string Name { get; set; } |
|||
|
|||
public byte Age { get; set; } |
|||
|
|||
public long Balance { get; set; } |
|||
|
|||
public string Location { get; set; } |
|||
} |
|||
} |
|||
```` |
|||
|
|||
You can create a new Specification class derived from the `Specification<Customer>`. |
|||
|
|||
**Example: A specification to select the customers with 18+ age:** |
|||
|
|||
````csharp |
|||
using System; |
|||
using System.Linq.Expressions; |
|||
using Volo.Abp.Specifications; |
|||
|
|||
namespace MyProject |
|||
{ |
|||
public class Age18PlusCustomerSpecification : Specification<Customer> |
|||
{ |
|||
public override Expression<Func<Customer, bool>> ToExpression() |
|||
{ |
|||
return c => c.Age >= 18; |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
You simply define a lambda [Expression](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/lambda-expressions) to define a specification. |
|||
|
|||
> Instead, you can directly implement the `ISpecification<T>` interface, but the `Specification<T>` base class much simplifies it. |
|||
|
|||
## Using the Specifications |
|||
|
|||
There are two common use cases of the specifications. |
|||
|
|||
### IsSatisfiedBy |
|||
|
|||
`IsSatisfiedBy` method can be used to check if a single object satisfies the specification. |
|||
|
|||
**Example: Throw exception if the customer doesn't satisfy the age specification** |
|||
|
|||
````csharp |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace MyProject |
|||
{ |
|||
public class CustomerService : ITransientDependency |
|||
{ |
|||
public async Task BuyAlcohol(Customer customer) |
|||
{ |
|||
if (!new Age18PlusCustomerSpecification().IsSatisfiedBy(customer)) |
|||
{ |
|||
throw new Exception( |
|||
"This customer doesn't satisfy the Age specification!" |
|||
); |
|||
} |
|||
|
|||
//TODO... |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
### ToExpression & Repositories |
|||
|
|||
`ToExpression()` method can be used to use the specification as Expression. In this way, you can use a specification to **filter entities while querying from the database**. |
|||
|
|||
````csharp |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Domain.Services; |
|||
|
|||
namespace MyProject |
|||
{ |
|||
public class CustomerManager : DomainService, ITransientDependency |
|||
{ |
|||
private readonly IRepository<Customer, Guid> _customerRepository; |
|||
|
|||
public CustomerManager(IRepository<Customer, Guid> customerRepository) |
|||
{ |
|||
_customerRepository = customerRepository; |
|||
} |
|||
|
|||
public async Task<List<Customer>> GetCustomersCanBuyAlcohol() |
|||
{ |
|||
var query = _customerRepository.Where( |
|||
new Age18PlusCustomerSpecification().ToExpression() |
|||
); |
|||
|
|||
return await AsyncExecuter.ToListAsync(query); |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
> Specifications are correctly translated to SQL/Database queries and executed efficiently in the DBMS side. While it is not related to the Specifications, see the [Repositories](Repositories.md) document if you want to know more about the `AsyncExecuter`. |
|||
|
|||
Actually, using the `ToExpression()` method is not necessary since the specifications are automatically casted to Expressions. This would also work: |
|||
|
|||
````csharp |
|||
var query = _customerRepository.Where( |
|||
new Age18PlusCustomerSpecification() |
|||
); |
|||
```` |
|||
|
|||
## Composing the Specifications |
|||
|
|||
One powerful feature of the specifications is that they are composable with `And`, `Or`, `Not` and `AndNot` extension methods. |
|||
|
|||
Assume that you have another specification as defined below: |
|||
|
|||
```csharp |
|||
using System; |
|||
using System.Linq.Expressions; |
|||
using Volo.Abp.Specifications; |
|||
|
|||
namespace MyProject |
|||
{ |
|||
public class PremiumCustomerSpecification : Specification<Customer> |
|||
{ |
|||
public override Expression<Func<Customer, bool>> ToExpression() |
|||
{ |
|||
return (customer) => (customer.Balance >= 100000); |
|||
} |
|||
} |
|||
} |
|||
``` |
|||
|
|||
You can combine the `PremiumCustomerSpecification` with the `Age18PlusCustomerSpecification` to query the count of premium adult customers as shown below: |
|||
|
|||
````csharp |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Domain.Services; |
|||
using Volo.Abp.Specifications; |
|||
|
|||
namespace MyProject |
|||
{ |
|||
public class CustomerManager : DomainService, ITransientDependency |
|||
{ |
|||
private readonly IRepository<Customer, Guid> _customerRepository; |
|||
|
|||
public CustomerManager(IRepository<Customer, Guid> customerRepository) |
|||
{ |
|||
_customerRepository = customerRepository; |
|||
} |
|||
|
|||
public async Task<int> GetAdultPremiumCustomerCountAsync() |
|||
{ |
|||
return await _customerRepository.CountAsync( |
|||
new Age18PlusCustomerSpecification() |
|||
.And(new PremiumCustomerSpecification()).ToExpression() |
|||
); |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
If you want to make this combination another reusable specification, you can create such a combination specification class deriving from the `AndSpecification`: |
|||
|
|||
````csharp |
|||
using Volo.Abp.Specifications; |
|||
|
|||
namespace MyProject |
|||
{ |
|||
public class AdultPremiumCustomerSpecification : AndSpecification<Customer> |
|||
{ |
|||
public AdultPremiumCustomerSpecification() |
|||
: base(new Age18PlusCustomerSpecification(), |
|||
new PremiumCustomerSpecification()) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
```` |
|||
|
|||
Now, you can re-write the `GetAdultPremiumCustomerCountAsync` method as shown below: |
|||
|
|||
````csharp |
|||
public async Task<int> GetAdultPremiumCustomerCountAsync() |
|||
{ |
|||
return await _customerRepository.CountAsync( |
|||
new AdultPremiumCustomerSpecification() |
|||
); |
|||
} |
|||
```` |
|||
|
|||
> You see the power of the specifications with these samples. If you change the `PremiumCustomerSpecification` later, say change the balance from `100.000` to `200.000`, all the queries and combined specifications will be effected by the change. This is a good way to reduce code duplication! |
|||
|
|||
## Discussions |
|||
|
|||
While the specification pattern is older than C# lambda expressions, it's generally compared to expressions. Some developers may think it's not needed anymore and we can directly pass expressions to a repository or to a domain service as shown below: |
|||
|
|||
````csharp |
|||
var count = await _customerRepository.CountAsync(c => c.Balance > 100000 && c.Age => 18); |
|||
```` |
|||
|
|||
Since ABP's [Repository](Repositories.md) supports Expressions, this is a completely valid use. You don't have to define or use any specification in your application and you can go with expressions. |
|||
|
|||
So, what's the point of a specification? Why and when should we consider to use them? |
|||
|
|||
### When To Use? |
|||
|
|||
Some benefits of using specifications: |
|||
|
|||
- **Reusabe**: Imagine that you need the Premium Customer filter in many places in your code base. If you go with expressions and do not create a specification, what happens if you later change the "Premium Customer" definition? Say you want to change the minimum balance from $100,000 to $250,000 and add another condition to be a customer older than 3 years. If you'd used a specification, you just change a single class. If you repeated (copy/pasted) the same expression everywhere, you need to change all of them. |
|||
- **Composable**: You can combine multiple specifications to create new specifications. This is another type of reusability. |
|||
- **Named**: `PremiumCustomerSpecification` better explains the intent rather than a complex expression. So, if you have an expression that is meaningful in your business, consider using specifications. |
|||
- **Testable**: A specification is a separately (and easily) testable object. |
|||
|
|||
### When To Not Use? |
|||
|
|||
- **Non business expressions**: Do not use specifications for non business-related expressions and operations. |
|||
- **Reporting**: If you are just creating a report, do not create specifications, but directly use `IQueryable` & LINQ expressions. You can even use plain SQL, views or another tool for reporting. DDD does not necessarily care about reporting, so the way you query the underlying data store can be important from a performance perspective. |
|||
@ -1,3 +1,75 @@ |
|||
## Value Objects |
|||
# Value Objects |
|||
|
|||
TODO |
|||
> An object that represents a descriptive aspect of the domain with no conceptual identity is called a VALUE OBJECT. |
|||
> |
|||
> (Eric Evans) |
|||
|
|||
Two [Entities](Entities.md) with the same properties but with different `Id`s are considered as different entities. However, Value Objects have no `Id`s and they are considered as equals if they have the same property values. |
|||
|
|||
## The ValueObject Class |
|||
|
|||
`ValueObject` is an abstract class that can be inherited to create a Value Object class. |
|||
|
|||
**Example: An Address class** |
|||
|
|||
````csharp |
|||
public class Address : ValueObject |
|||
{ |
|||
public Guid CityId { get; private set; } |
|||
|
|||
public string Street { get; private set; } |
|||
|
|||
public int Number { get; private set; } |
|||
|
|||
private Address() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public Address( |
|||
Guid cityId, |
|||
string street, |
|||
int number) |
|||
{ |
|||
CityId = cityId; |
|||
Street = street; |
|||
Number = number; |
|||
} |
|||
|
|||
protected override IEnumerable<object> GetAtomicValues() |
|||
{ |
|||
yield return Street; |
|||
yield return CityId; |
|||
yield return Number; |
|||
} |
|||
} |
|||
```` |
|||
|
|||
* A Value Object class must implement the `GetAtomicValues()` method to return the primitive values. |
|||
|
|||
### ValueEquals |
|||
|
|||
`ValueObject.ValueEquals(...)` method is used to check if two Value Objects are equals. |
|||
|
|||
**Example: Check if two addresses are equals** |
|||
|
|||
````csharp |
|||
Address address1 = ... |
|||
Address address2 = ... |
|||
|
|||
if (address1.ValueEquals(address2)) //Check equality |
|||
{ |
|||
... |
|||
} |
|||
```` |
|||
|
|||
## Best Practices |
|||
|
|||
Here are some best practices when using Value Objects: |
|||
|
|||
- Design a value object as **immutable** (like the Address above) if there is not a good reason for designing it as mutable. |
|||
- The properties that make up a Value Object should form a conceptual whole. For example, CityId, Street and Number shouldn't be separate properties of a Person entity. This also makes the Person entity simpler. |
|||
|
|||
## See Also |
|||
|
|||
* [Entities](Entities.md) |
|||
@ -0,0 +1,15 @@ |
|||
using Volo.Abp.Bundling; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme |
|||
{ |
|||
public class BundleContributer : BaseBundleContributer |
|||
{ |
|||
public override string[] GetStyles() |
|||
{ |
|||
return new string[] |
|||
{ |
|||
"_content/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/libs/abp/css/theme.css", |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.Bundling; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming |
|||
{ |
|||
public class BundleContributer : BaseBundleContributer |
|||
{ |
|||
public override string[] GetStyles() |
|||
{ |
|||
return new string[] |
|||
{ |
|||
"_content/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/libs/bootstrap/css/bootstrap.min.css", |
|||
"_content/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/libs/fontawesome/css/all.css", |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 262 B |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 761 B |
|
Before Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 231 B |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 242 B |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 541 B |
|
Before Width: | Height: | Size: 498 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 609 B |
|
Before Width: | Height: | Size: 192 B |
|
Before Width: | Height: | Size: 290 B |
|
Before Width: | Height: | Size: 383 B |
|
Before Width: | Height: | Size: 294 B |
|
Before Width: | Height: | Size: 538 B |
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 499 B |
|
Before Width: | Height: | Size: 292 B |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 116 KiB |
|
Before Width: | Height: | Size: 228 B |
|
Before Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 568 B |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 582 B |
|
Before Width: | Height: | Size: 254 B |
|
Before Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 708 B |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 507 B |
|
Before Width: | Height: | Size: 632 B |
|
Before Width: | Height: | Size: 469 B |
|
Before Width: | Height: | Size: 295 B |
|
Before Width: | Height: | Size: 283 B |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 574 B |
|
Before Width: | Height: | Size: 824 B |
|
Before Width: | Height: | Size: 743 B |
|
Before Width: | Height: | Size: 289 B |
|
Before Width: | Height: | Size: 293 B |
|
Before Width: | Height: | Size: 573 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 682 B |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 232 B |
|
Before Width: | Height: | Size: 221 B |
|
Before Width: | Height: | Size: 585 B |
|
Before Width: | Height: | Size: 235 B |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 382 KiB |
|
Before Width: | Height: | Size: 305 B |
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 352 B |
|
Before Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 817 B |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 257 B |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 240 B |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 759 B |
|
Before Width: | Height: | Size: 534 B |
|
Before Width: | Height: | Size: 292 B |
|
Before Width: | Height: | Size: 278 B |
|
Before Width: | Height: | Size: 232 B |