{"id":20858613,"url":"https://github.com/giacomelli/kissspecifications","last_synced_at":"2025-06-15T18:33:11.066Z","repository":{"id":8086559,"uuid":"9500337","full_name":"giacomelli/KissSpecifications","owner":"giacomelli","description":"A KISS approach for specification pattern","archived":false,"fork":false,"pushed_at":"2023-05-31T19:22:00.000Z","size":8542,"stargazers_count":19,"open_issues_count":3,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-10-10T22:39:53.132Z","etag":null,"topics":["c-sharp","design-pattern","specification-pattern"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/giacomelli.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-04-17T15:00:59.000Z","updated_at":"2023-06-08T07:24:01.000Z","dependencies_parsed_at":"2024-06-19T22:49:41.376Z","dependency_job_id":"1784f8fd-59b8-466a-a2b8-bd40f3c2ba3f","html_url":"https://github.com/giacomelli/KissSpecifications","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giacomelli%2FKissSpecifications","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giacomelli%2FKissSpecifications/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giacomelli%2FKissSpecifications/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giacomelli%2FKissSpecifications/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/giacomelli","download_url":"https://codeload.github.com/giacomelli/KissSpecifications/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225130753,"owners_count":17425506,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c-sharp","design-pattern","specification-pattern"],"created_at":"2024-11-18T04:46:39.023Z","updated_at":"2024-11-18T04:46:39.631Z","avatar_url":"https://github.com/giacomelli.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"KissSpecifications\n==================\n\nA KISS approach for specification pattern.\nhttp://en.wikipedia.org/wiki/Specification_pattern\n\nSetup\n========\n\nNuGet\n--------\nPM\u003e Install-Package KissSpecifications\n\nFeatures\n========\n- ISpecification : interface to define any kind of specification\n- SpecificationBase\u003cTTarget\u003e : base class to easy create new specifications\n- SpecificationService : Service class with features to validate specifications\n- SpecificationGroups : attribute to define groups for a specification\n- Commons specifications\n\t- MustHaveNullOrDefaultPropertySpecification \n\t- MustNotBeNullSpecification \n\t- MustNotHaveEmptyPropertyTextSpecification\n\t- MustNotHaveNullOrDefaultPropertySpecification\n- Globalization\n\t- IGlobalizationResolver interface to define any kind of globalization for commons specifications  \n\nUsing\n========\n* Create your specification classes:\n\n```csharp\n\npublic class CustomerMustHaveValidNameSpecification : SpecificationBase\u003cstring\u003e\n{\n\n\t\t#region Constants\n\t\tpublic const int MinCustomerName = 5;\n\t\tpublic const int MaxCustomerName = 30;\n\t\t#endregion\n\n\t\t#region Methods\n\t\tpublic override bool IsSatisfiedBy(string target)\n\t\t{\n\t\t\tif (String.IsNullOrWhiteSpace(target))\n\t\t\t{\n\t\t\t\tNotSatisfiedReason = \"Customer name should be specified.\";\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (target.Length \u003c MinCustomerName)\n\t\t\t{\n\t\t\t\tNotSatisfiedReason = String.Format(CultureInfo.CurrentUICulture, \"The minimum length for customer name is {0} chars.\", MinCustomerName);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (target.Length \u003e MaxCustomerName)\n\t\t\t{\n\t\t\t\tNotSatisfiedReason = String.Format(CultureInfo.CurrentUICulture, \"The maximum length for customer name is {0} chars.\", MaxCustomerName);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\t\t#endregion\n}\n\n```\n\n* Call the SpecificationService on your Domain method:\n\n```csharp\n\npublic static class CustomerService\n{\n\n\tpublic static void CreateCustomer(Customer customer)\n\t{\n\t\tSpecificationService.ThrowIfAnySpecificationIsNotSatisfiedBy(customer, new CustomerCreationSpecification());\n\n\t\t// TODO: Logic to create customer...\n\t}\n}\n\n```\n\nCreate Groups of specification\n========\n\nDefining groups\n--------\nYou can use any object to declare a group key for your specification, but is always better to define constants or enumerators.\n\n```csharp\n\n/// \u003csummary\u003e\n/// Just a enum to define my specification groups.\n/// \u003c/summary\u003e\npublic enum SampleSpecificationGroup\n{\n\tSave = 0,\n\tSendEmail = 1,\n}\n\n\n[SpecificationGroups (SampleSpecificationGroup.Save, \"Sell\")]\npublic class CustomerMustHaveNameSpecification : ISpecification\u003cCustomer\u003e\n{\n\t...\n}\n\n[SpecificationGroups (1, 5)]\npublic class CustomerMustHaveValidAccountSpecification : ISpecification\u003cCustomer\u003e\n{\n\t...\n}\n\n[SpecificationGroups (SampleSpecificationGroup.SendEmail)]\npublic class CustomerMustHaveEmailSpecification : ISpecification\u003cCustomer\u003e\n{\n\t...\n}\n\n[SpecificationGroups (Constants.AConstantValue, \"Sell\", 1)]\npublic class CustomerCanNotHaveDebitSpecification : ISpecification\u003cCustomer\u003e\n{\n\t...\n}\n\n```\n\nValidate\n--------\n\n* Call the SpecificationService on your Domain method defining groups that you want to validate:\n\n```csharp\n\npublic static class CustomerService\n{\n\n\tpublic static void CreateCustomer(Customer customer)\n\t{\n\t\tSpecificationService.ThrowIfAnySpecificationIsNotSatisfiedBy(customer, SampleSpecificationGroup.Save);\n\n\t\t// TODO: Logic to create customer...\n\t}\n}\n\n```\n\nBest practices\n========\nNaming\n--------\nLet everyone know exactly what you are trying to specify! Create meaningful names for your specification classes.\nIt will keep your code readable and easy to maintain.\n\n```csharp\n\npublic static class CustomerService\n{\n\n\tpublic static void CreateCustomer(Customer customer)\n\t{\n\t\tSpecificationService.ThrowIfAnySpecificationIsNotSatisfiedBy(\n\t\t\tcustomer, \n\t\t\tnew CustomerMustHaveNameSpecification(),\n\t\t\tnew CustomerMustHaveValidAccountSpecification(),\n\t\t\tnew CustomerMustHaveEmailSpecification(),\n\t\t\tnew CustomerCanNotHaveDebitSpecification());\n\n\t\t// TODO: Logic to create customer...\n\t}\n}\n\n```\n\nLicense\n======\n\nLicensed under the The MIT License (MIT).\nIn others words, you can use this library for developement any kind of software: open source, commercial, proprietary and alien.\n\n\nChange Log\n======\n - 1.1.9 HelperSharp updated.\n - 1.1.8 Added MustExistsSpecification.\n - 1.1.7 Added MustHaveUniqueTextSpecification.\n - 1.1.6 Added specification groups feature.\n - 1.1.5 Added MustNotBeNullSpecification.\n - 1.1.4 \n\t* KissSpecificationsConfig\n\t* IGlobalizationProvider\n\t* Commons specifications\n\t\t* MustHaveNullOrDefaultPropertySpecification\n\t\t* MustNotHaveEmptyPropertyTextSpecification\n\t\t* MustNotHaveNullOrDefaultPropertySpecification\n - 1.1.0 Added SpecificationService.ThrowIfAnySpecificationIsNotSatisfiedByAny.\n - 1.0.0 First version.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiacomelli%2Fkissspecifications","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgiacomelli%2Fkissspecifications","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiacomelli%2Fkissspecifications/lists"}