{"id":18909738,"url":"https://github.com/dogmasolutions/analyzers","last_synced_at":"2025-09-04T02:41:11.911Z","repository":{"id":144107557,"uuid":"445464327","full_name":"DogmaSolutions/Analyzers","owner":"DogmaSolutions","description":"A set of Roslyn Analyzer aimed to enforce some design good practices and code quality (QA) rules.","archived":false,"fork":false,"pushed_at":"2025-04-04T19:57:11.000Z","size":294,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-04T20:33:56.129Z","etag":null,"topics":["best-practice","best-practices","csharp","csharp-code","design-patterns","quality-assurance","roslyn-analyzer","roslyn-analyzers"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DogmaSolutions.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2022-01-07T09:19:48.000Z","updated_at":"2025-04-04T19:57:15.000Z","dependencies_parsed_at":null,"dependency_job_id":"b30f7355-a076-4819-b0f9-4c5445dc5b50","html_url":"https://github.com/DogmaSolutions/Analyzers","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/DogmaSolutions%2FAnalyzers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DogmaSolutions%2FAnalyzers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DogmaSolutions%2FAnalyzers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DogmaSolutions%2FAnalyzers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DogmaSolutions","download_url":"https://codeload.github.com/DogmaSolutions/Analyzers/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248526323,"owners_count":21118863,"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":["best-practice","best-practices","csharp","csharp-code","design-patterns","quality-assurance","roslyn-analyzer","roslyn-analyzers"],"created_at":"2024-11-08T09:35:00.577Z","updated_at":"2025-04-12T06:24:25.504Z","avatar_url":"https://github.com/DogmaSolutions.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Dogma Solutions Roslyn Analyzers\n\n[![DogmaSolutions.Analyzers on NuGet](https://img.shields.io/nuget/v/DogmaSolutions.Analyzers.svg)](https://www.nuget.org/packages/DogmaSolutions.Analyzers/)\n\nA set of Roslyn Analyzer aimed to enforce some design good practices and code quality (QA) rules.\n\n# Rules structure\n\nThis section describes the rules included into this package.\n\nEvery rule is accompanied by the following information and clues:\n\n- **Category** → identify the area of interest of the rule, and can have one of the following values: _Design / Naming / Style / Usage / Performance / Security_\n- **Severity** → state the default severity level of the rule. The severity level can be changed by editing the _.editorconfig_ file used by the project/solution. Possible values are enumerated by\n  the [DiagnosticSeverity enum](https://docs.microsoft.com/en-us/dotnet/api/microsoft.codeanalysis.diagnosticseverity)\n- **Description, motivations and fixes** → a detailed explanation of the detected issue, and a brief description on how to change your code in order to solve it.\n- **See also** → a list of similar/related rules, or related knowledge base\n\n# Rules list\n\n| Id                | Category    | Description                                                                                                                                                                                                | Default severity | Is enabled | Code fix |\n|-------------------|-------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------|------------|----------|\n| [DSA001](#dsa001) | Design      | [WebApi controller methods](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.controllerbase) should not contain data-manipulation business logics through a **LINQ query expression**. | ⚠ Warning        | ✅          | ❌        |\n| [DSA002](#dsa002) | Design      | [WebApi controller methods](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.controllerbase) should not contain data-manipulation business logics through a **LINQ fluent query**.     | ⚠ Warning        | ✅          | ❌        |\n| [DSA003](#dsa003) | Code Smells | Use `String.IsNullOrWhiteSpace` instead of `String.IsNullOrEmpty`                                                                                                                                          | ⚠ Warning        | ✅          | ❌        |\n| [DSA004](#dsa004) | Code Smells | Use `DateTime.UtcNow` instead of `DateTime.Now`                                                                                                                                                            | ⚠ Warning        | ✅          | ❌        |\n| [DSA005](#dsa005) | Code Smells | Potential non-deterministic point-in-time execution                                                                                                                                                        | ⛔ Error          | ✅          | ❌        |\n| [DSA006](#dsa006) | Code Smells | General exceptions should not be thrown by user code                                                                                                                                                       | ⛔ Error          | ✅          | ❌        |\n| [DSA007](#dsa007) | Code Smells | When initializing a lazy field, use a robust locking pattern, i.e. the \"if-lock-if\" (aka \"double checked locking\")                                                                                         | ⚠ Warning        | ✅          | ❌        |\n| [DSA008](#dsa008) | Bug         | The Required Attribute has no impact on a not-nullable DateTime                                                                                                                                            | ⛔ Error          | ✅          | ❌        |\n| [DSA009](#dsa009) | Bug         | The Required Attribute has no impact on a not-nullable DateTimeOffset                                                                                                                                      | ⛔ Error          | ✅          | ❌        |\n| [DSA011](#dsa011) | Design      | Avoid lazily initialized, self-contained, static singleton properties                                                                                                                                      | ⚠ Warning        | ✅          | ❌        |\n\n---\n\n# DSA001\n\nDon't use Entity Framework to launch LINQ queries in a WebApi controller.\n\n- **Category**: Design\n- **Severity**: Warning ⚠\n- **Related rules**: [DSA002](#dsa002)\n\n## Description\n\n[WebApi controller methods](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.controllerbase) should not contain data-manipulation business logics through a **LINQ query expression**.  \nIn the analyzed code, a [WebApi controller method](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.controllerbase) is\nusing [Entity Framework DbContext](https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.dbcontext) to directly manipulate data through a LINQ query expression.  \nWebApi controllers should not contain data-manipulation business logics.\n\n## See also\n\nThis is a typical violation of the [\"Single Responsibility\" rule](https://en.wikipedia.org/wiki/Single-responsibility_principle) of the [\"SOLID\" principles](https://en.wikipedia.org/wiki/SOLID),\nbecause the controller is doing too many things outside its own purpose.\n\n## Fix / Mitigation\n\nIn order to fix the problem, the code could be modified in order to rely on the [\"Indirection pattern\"](https://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Indirection) and maximize\nthe [\"Low coupling evalutative pattern\"](https://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Low_coupling) of the [\"GRASP\"](https://en.wikipedia.org/wiki/GRASP_(object-oriented_design))\nprinciples.\nMove the data-manipulation business logics into a more appropriate class, or even better, an injected service.\n\n## Rule configuration\n\nIn order to change the severity level of this rule, change/add this line in the `.editorconfig` file:\n\n```\n# DSA001: WebApi controller methods should not contain data-manipulation business logics through a LINQ query expression.\ndotnet_diagnostic.DSA001.severity = error\n```\n\n## Code sample\n\n```csharp\npublic class MyEntitiesController : ControllerBase\n{\n protected MyDbContext DbContext { get; }\n\n public MyEntitiesController(MyDbContext dbContext)\n {\n     DbContext = dbContext;\n }\n\n [HttpGet]\n public IEnumerable\u003cMyEntity\u003e GetAll_NotOk()\n {\n     // this WILL trigger the rule\n     var query = from entities in DbContext.MyEntities where entities.Id \u003e 0 select entities;\n     return query.ToList(); \n }\n\n [HttpPost]\n public IEnumerable\u003clong\u003e GetAll_Ok()\n {\n     // this WILL NOT trigger the rule\n     var query = DbContext.MyEntities.Where(entities =\u003e entities.Id \u003e 0).Select(entities=\u003eentities.Id);\n     return query.ToList(); \n }\n}\n```\n\n---\n\n# DSA002\n\nDon't use an Entity Framework `DbSet` to launch queries in a WebApi controller.\n\n- **Category**: Design\n- **Severity**: Warning ⚠\n- **Related rules**: [DSA001](#dsa001)\n\n## Description\n\n[WebApi controller methods](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.controllerbase) should not contain data-manipulation business logics through a **LINQ fluent query**.  \nIn the analyzed code, a [WebApi controller method](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.controllerbase) is\nusing [Entity Framework DbSet](https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.dbset-1) to directly manipulate data through a LINQ fluent query.  \nWebApi controllers should not contain data-manipulation business logics.\n\n## See also\n\nThis is a typical violation of the [\"Single Responsibility\" rule](https://en.wikipedia.org/wiki/Single-responsibility_principle) of the [\"SOLID\" principles](https://en.wikipedia.org/wiki/SOLID),\nbecause the controller is doing too many things outside its own purpose.\n\n## Fix / Mitigation\n\nIn order to fix the problem, the code could be modified in order to rely on the [\"Indirection pattern\"](https://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Indirection) and maximize\nthe [\"Low coupling evalutative pattern\"](https://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Low_coupling) of the [\"GRASP\"](https://en.wikipedia.org/wiki/GRASP_(object-oriented_design))\nprinciples.   \nMove the data-manipulation business logics into a more appropriate class, or even better, an injected service.\n\n## Rule configuration\n\nIn order to change the severity level of this rule, change/add this line in the `.editorconfig` file:\n\n```\n# DSA002: WebApi controller methods should not contain data-manipulation business logics through a LINQ fluent query.\ndotnet_diagnostic.DSA002.severity = error\n```\n\n## Code sample\n\n```csharp\npublic class MyEntitiesController : Microsoft.AspNetCore.Mvc.ControllerBase\n{\n protected MyDbContext DbContext { get; }\n\n public MyEntitiesController(MyDbContext dbContext)\n {\n     this.DbContext = dbContext;\n }\n\n [HttpGet]\n public IEnumerable\u003cMyEntity\u003e GetAll0()\n {\n     // this WILL NOT trigger the rule\n     var query = from entities in DbContext.MyEntities where entities.Id \u003e 0 select entities;\n     return query.ToList(); \n }\n\n [HttpPost]\n public IEnumerable\u003clong\u003e GetAll1()\n {\n     // this WILL trigger the rule\n     var query = DbContext.MyEntities.Where(entities =\u003e entities.Id \u003e 0).Select(entities=\u003eentities.Id);\n     return query.ToList(); \n }\n}\n```\n\n---\n\n# DSA003\n\nUse `IsNullOrWhiteSpace` instead of `String.IsNullOrEmpty`.\n\n- **Category**: Code smells\n- **Severity**: Warning ⚠\n\n## Description\n\nUsually, business logics distinguish between \"string with content\", and \"string NULL or without meaningful content\".  \nThus, statistically speaking, almost every call to `string.IsNullOrEmpty` could or should be replaced by a call to `string.IsNullOrWhiteSpace`, because in the large majority of cases, a string\ncomposed by only spaces, tabs, and return chars is not considered valid because it doesn't have \"meaningful content\".  \nIn most cases, `string.IsNullOrEmpty` is used by mistake, or has been written when `string.IsNullOrWhiteSpace` was not available.\n\n## Fix / Mitigation\n\nDon't use `string.IsNullOrEmpty`. Use `string.IsNullOrWhiteSpace` instead.\n\n## Rule configuration\n\nIn order to change the severity level of this rule, change/add this line in the `.editorconfig` file:\n\n```\n# DSA003: Use String.IsNullOrWhiteSpace instead of String.IsNullOrEmpty\ndotnet_diagnostic.DSA003.severity = error\n```\n\n## Code sample\n\n```csharp\npublic class MyClass\n{\n\n public bool IsOk(string s)\n {\n     // this WILL NOT trigger the rule\n     return string.IsNullOrWhiteSpace(s);\n }\n\n public bool IsNotOk(string s)\n {\n     // this WILL trigger the rule\n     return string.IsNullOrEmpty(s);\n }\n\n}\n```\n\n---\n\n# DSA004\n\nUse `DateTime.UtcNow` instead of `DateTime.Now`.\n\n- **Category**: Code smells\n- **Severity**: Warning ⚠\n\n## Description\n\nUsing `DateTime.Now` into business logics potentially leads to many different problems:\n\n- Incoherence between nodes or processes running in different timezones (even in the same country, i.e. USA, Soviet Union, China, etc)\n- Unexpected behaviours in-between legal time changes\n- Code conversion problems and loss of timezone info when saving/loading data to/from a datastore\n\n## See also\n\nSecurity-wise, this is correlated to the CWE category “7PK” ([CWE-361](https://cwe.mitre.org/data/definitions/361.html))  \nCit:\n*\"This category represents one of the phyla in the Seven Pernicious Kingdoms vulnerability classification. It includes weaknesses related to the improper management of time and state in an environment\nthat supports simultaneous or near-simultaneous computation by multiple systems, processes, or threads. According to the authors of the Seven Pernicious Kingdoms, \"Distributed computation is about\ntime and state. That is, in order for more than one component to communicate, state must be shared, and all that takes time. Most programmers anthropomorphize their work. They think about one thread\nof control carrying out the entire program in the same way they would if they had to do the job themselves. Modern computers, however, switch between tasks very quickly, and in multi-core, multi-CPU,\nor distributed systems, two events may take place at exactly the same time. Defects rush to fill the gap between the programmer's model of how a program executes and what happens in reality. These\ndefects are related to unexpected interactions between threads, processes, time, and information. These interactions happen through shared state: semaphores, variables, the file system, and,\nbasically, anything that can store information.\"*\n\n## Fix / Mitigation\n\nDon't use `DateTime.Now`. Use `DateTime.UtcNow` instead\n\n## Rule configuration\n\nIn order to change the severity level of this rule, change/add this line in the `.editorconfig` file:\n\n```\n# DSA004: Use DateTime.UtcNow instead of DateTime.Now\ndotnet_diagnostic.DSA004.severity = error\n```\n\n## Code sample\n\n```csharp\npublic class MyClass\n{\n\n public DateTime IsOk()\n {\n     // this WILL NOT trigger the rule\n     return DateTime.UtcNow;\n }\n\n public DateTime IsNotOk()\n {\n     // this WILL trigger the rule\n     return DateTime.Now;\n }\n\n}\n```\n\n---\n\n# DSA005\n\nPotential non-deterministic point-in-time execution due to multiple usages of `DateTime.UtcNow` or `DateTime.Now` in the same method.\n\n- **Category**: Code smells\n- **Severity**: Error ⛔\n\n## Description\n\nAn execution flow must always be as deterministic as possible.\nThis means that all decisions inside a scope or algorithm must be performed on a \"stable\" and immutable set of parameters/conditions.\nWhen dealing with dates and times, always ensure that the point-in-time reference is fixed, otherwise the algorithm would work on a \"sliding window\", leading to unpredictable results.\nThis is particularly impacting in:\n\n- datasource-dependent flows\n- slow-running algorithms\n- and in-between legal time changes.\n\n## See also\n\nSecurity-wise, this is correlated to the CWE category “7PK” ([CWE-361](https://cwe.mitre.org/data/definitions/361.html))  \nCit:\n*\"This category represents one of the phyla in the Seven Pernicious Kingdoms vulnerability classification. It includes weaknesses related to the improper management of time and state in an environment\nthat supports simultaneous or near-simultaneous computation by multiple systems, processes, or threads. According to the authors of the Seven Pernicious Kingdoms, \"Distributed computation is about\ntime and state. That is, in order for more than one component to communicate, state must be shared, and all that takes time. Most programmers anthropomorphize their work. They think about one thread\nof control carrying out the entire program in the same way they would if they had to do the job themselves. Modern computers, however, switch between tasks very quickly, and in multi-core, multi-CPU,\nor distributed systems, two events may take place at exactly the same time. Defects rush to fill the gap between the programmer's model of how a program executes and what happens in reality. These\ndefects are related to unexpected interactions between threads, processes, time, and information. These interactions happen through shared state: semaphores, variables, the file system, and,\nbasically, anything that can store information.\"*\n\n## Fix/Mitigation\n\nIn order to avoid problems, apply one of these, depending on the situation:\n\n- When measuring elapsed time, use a `StopWatch.StartNew()` combined with `StopWatch.Elapsed`\n- When NOT measuring elapsed time, set a `var now = DateTime.UtcNow` variable at the top of the method, or at the beginning of an execution flow/algorithm, and reuse that variable in all places\n  instead of `DateTime.***Now`.\n\n## Rule configuration\n\nIn order to change the severity level of this rule, change/add this line in the `.editorconfig` file:\n\n```\n# DSA005: Potential non-deterministic point-in-time execution\ndotnet_diagnostic.DSA005.severity = error\n```\n\n## Code sample\n\n```csharp\npublic class MyClass\n{\n\n public bool IsOk(string s)\n {     \n     var now = DateTime.UtcNow; // fixed point-in-time reference\n     \n     DoSomething(now); // this WILL NOT trigger the rule\n     \n     for(int i; i \u003c 10; i++)\n     {\n       DoOtherThings(now);  // this WILL NOT trigger the rule\n     }\n }\n\n public bool IsNotOk(string s)\n {   \n     DoSomething(DateTime.UtcNow); // this WILL trigger the rule\n     \n     for(int i; i \u003c 10; i++)\n     {\n       DoOtherThings(DateTime.UtcNow);  // this WILL trigger the rule\n     }\n }\n\n}\n```\n\n---\n\n# DSA006\n\nGeneral exceptions should not be thrown by user code.\n\n- **Category**: Code smells\n- **Severity**: Error ⛔\n\n## Description\n\nGeneral exceptions should never be thrown, because throwing them, prevents calling methods from discriminating between system-generated exceptions, and application-generated errors.  \nThis is a bad smell, and could lead to stability and security concerns.  \nGeneral exceptions that triggers this rule are:\n\n- `Exception`\n- `SystemException`\n- `ApplicationException`\n- `IndexOutOfRangeException`\n- `NullReferenceException`\n- `OutOfMemoryException`\n- `ExecutionEngineException`\n\n## See also\n\nSecurity-wise, this is correlated to [MITRE, CWE-397 - Declaration of Throws for Generic Exception](https://cwe.mitre.org/data/definitions/397)\n\n## Fix/Mitigation\n\nUse scenario-specific exceptions, i.e. `ArgumentException`, `ArgumentNullException`, `InvalidOperationException`, etc.\n\n## Rule configuration\n\nIn order to change the severity level of this rule, change/add this line in the `.editorconfig` file:\n\n```\n# DSA006: General exceptions should never be thrown. \ndotnet_diagnostic.DSA006.severity = error\n```\n\n## Code sample\n\n```csharp\npublic class MyClass\n{\n    \n    public void IsOk(int id)\n    {     \n      if(id \u003c 0) // this is OK, and will NOT be matched by the rule\n        throw new ArgumentException(nameof(id),\"Invalid id\");\n    }\n\n    public void IsNotOk(int id)\n    {     \n      if(id \u003c 0) // this NOT OK, and will be matched by the rule\n        throw new SystemException(\"Invalid id\");\n    }\n\n}\n```\n\n---\n\n# DSA007\n\nWhen initializing a lazy field (and in particular fields contains the instance of a singleton object), use a robust locking pattern, i.e. the “if-lock-if” (aka “double checked locking”)\n\n- **Category**: Code smells\n- **Severity**: Warning ⚠\n\n## Description\n\nCit. Wikipedia:  \n*The \"double-checked locking\" (also known as \"double-checked locking optimization\") is a software design pattern used to reduce the overhead of acquiring a lock by testing the locking criterion (the \"\nlock hint\") before acquiring the lock.\nLocking occurs only if the locking criterion check indicates that locking is required.\nThe pattern is typically used to reduce locking overhead when implementing \"lazy initialization\" in a multi-threaded environment, especially as part of the Singleton pattern.\nLazy initialization avoids initializing a value until the first time it is accessed.*\n\n## See also\n\n- [Wikipedia: Double-checked_locking](https://en.wikipedia.org/wiki/Double-checked_locking)\n- [Microsoft Documentation: Managed Threading Best Practices](https://docs.microsoft.com/en-us/dotnet/standard/threading/managed-threading-best-practices)\n- [MITRE, CWE-667: Improper Locking (4.16)](https://cwe.mitre.org/data/definitions/667.html)\n- [MITRE, CWE-413: Improper Resource Locking (4.16)](https://cwe.mitre.org/data/definitions/413.html)\n\n## Fix/Mitigation\n\nInstead of just writing something like this....\n\n```cs\npublic class MyClass \n{    \n  private string _theField;\n  private readonly object _theLock = new object();\n\n  public void IsOk(int id)\n  {     \n    lock(_theLock){ // ❌ too early, very wastefull, poor performances\n        if(_theField == null) { \n           _theField = ComputeExpensiveValue(id);\n        }\n    }\n  }\n}\n```\n\n... or something like this....\n\n```cs\npublic class MyClass \n{    \n  private string _theField;\n  private readonly object _theLock = new object();\n\n  public void IsOk(int id)\n  {     \n    if(_theField == null) { \n        lock(_theLock){ // ❌ too late, and thread-unsafe      \n           _theField = ComputeExpensiveValue(id); // ⚠ this could be executed multiple times !\n        }\n    }\n  }\n}\n```\n\n... use the following *if-lock-if* pattern:\n\n```cs\npublic class MyClass \n{    \n  private string _theField;\n  private readonly object _theLock = new object();\n\n  public void IsOk(int id)\n  {     \n    if(_theField == null) { // ✅ efficient and fast pre-check (few nanoseconds)\n        lock(_theLock){ // ✅ protects againts race conditions and multithreading\n            if(_theField == null) { // ✅ only if really needed, safely initialize\n               _theField = ComputeExpensiveValue(id); // ✅ guaranteed to be executed only once\n            }\n        }\n    }\n  }\n}\n```\n\n## Rule configuration\n\nIn order to change the severity level of this rule, change/add this line in the `.editorconfig` file:\n\n```\n# DSA007: Use the double-checked lazy initialization pattern\ndotnet_diagnostic.DSA007.severity = warning\n```\n\n---\n\n# DSA008\n\nThe [Required Attribute](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.requiredattribute) has no impact on a\nnot-nullable [DateTime](https://learn.microsoft.com/it-it/dotnet/api/system.datetime) property.\n\n- **Category**: Bug\n- **Severity**: ⛔ Error\n\n## Description\n\nIs a common misunderstanding that the [Required Attribute](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.requiredattribute) is somehow able to validate a\nnot-nullable [DateTime](https://learn.microsoft.com/it-it/dotnet/api/system.datetime) property.  \nIn reality, not-nullable, not-string types are ignored by the [Required Attribute](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.requiredattribute), so it doesn't\nmake any sense to use it in this context.\n\n## Fix/Mitigation\n\nRemove the [Required Attribute](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.requiredattribute), or make the property nullable.\nIf a \"valid date\"-like validation is needed, use [Range Attribute](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.rangeattribute).\n\n## See also\n\n- [DSA009](#dsa009) - The Required Attribute has no impact on a not-nullable DateTimeOffset\n- [Required Attribute](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.requiredattribute)\n- [Range Attribute](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.rangeattribute)\n- [DateTime](https://learn.microsoft.com/it-it/dotnet/api/system.datetime)\n\n## Rule configuration\n\nIn order to change the severity level of this rule, change/add this line in the `.editorconfig` file:\n\n```\n# DSA008: The Required Attribute has no impact on a not-nullable DateTime\ndotnet_diagnostic.DSA008.severity = warning\n```\n\n---\n\n# DSA009\n\nThe [Required Attribute](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.requiredattribute) has no impact on a\nnot-nullable [DateTimeOffset](https://learn.microsoft.com/it-it/dotnet/api/system.DateTimeOffset) property.\n\n- **Category**: Bug\n- **Severity**: ⛔ Error\n\n## Description\n\nIs a common misunderstanding that the [Required Attribute](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.requiredattribute) is somehow able to validate a\nnot-nullable [DateTimeOffset](https://learn.microsoft.com/it-it/dotnet/api/system.DateTimeOffset) property.  \nIn reality, not-nullable, not-string types are ignored by the [Required Attribute](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.requiredattribute), so it doesn't\nmake any sense to use it in this context.\n\n## Fix/Mitigation\n\nRemove the [Required Attribute](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.requiredattribute), or make the property nullable.\nIf a \"valid date\"-like validation is needed, use [Range Attribute](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.rangeattribute).\n\n## See also\n\n- [DSA008](#dsa008) - The Required Attribute has no impact on a not-nullable DateTime\n- [Required Attribute](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.requiredattribute)\n- [Range Attribute](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.rangeattribute)\n- [DateTimeOffset](https://learn.microsoft.com/it-it/dotnet/api/system.DateTimeOffset)\n\n## Rule configuration\n\nIn order to change the severity level of this rule, change/add this line in the `.editorconfig` file:\n\n```\n# DSA009: The Required Attribute has no impact on a not-nullable DateTimeOffset\ndotnet_diagnostic.DSA009.severity = warning\n```\n\n---\n\n# DSA011\n\nAvoid lazily initialized, self-contained, static singleton properties\n\n- **Category**: Design\n- **Severity**: ⚠ Warning\n\n## Description\nThe [Singleton Pattern](https://en.wikipedia.org/wiki/Singleton_pattern) is subject of many controversies. Technically, there is nothing wrong with it, but its usefulness and robustness is very implementation-dependent, and in some cases it's seen as an anti-pattern. \n\nA good strategy to make use of this pattern, is to use an IoC/DI framework that ensures proper thread-safeness, dependencies management, and resources allocation/deallocation. \n```cs\n// Good/Safe implementation, based on Microsoft IoC/DI\nservices.AddSingleton\u003cIMyService, MyService\u003e();  \n```\n\nA simpler but **very problematic** strategy relies on directly exposing a public static property in the singleton class, like this.\n```cs\npublic class MyClass\n{\n    private static MyClass _instance;\n    \n    // Bad practice: \n    // - fragile, because lacks proper locking\n    // - badly designed, because forces the caller to \"know\" the implementor class\n    public static MyClass Instance =\u003e _instance??=new MyClass();\n}\n```\n\nSelf-contained static singleton properties, particularly when they involve lazy initialization within the property itself, can lead to several problems, especially in multithreaded environments.\nDue to their static nature, they are also difficult to test, and could manifest unpredictable results if the testing framework (or the tests) doesn't clean the static instances in-between sessions. Also, they force the caller to know the implementor class, instead of just an abstraction (i.e. an interface implemented by the singleton class).\n\nThis analyzer aims to find occurrences of this kind of ill-conceived implementations.  \nThe following patterns are matched:\n\n```cs\npublic class MyClass\n{\n    private static MyClass _instance;\n\n    public static MyClass Instance\n    {\n        get\n        {\n            if (_instance == null)\n                _instance = new MyClass();\n            return _instance;\n        }\n    }\n}\n```\n\n```cs\npublic class MyClass\n{\n    private static MyClass _instance;\n\n    public static MyClass Instance\n    {\n        get\n        {\n            if (_instance != null)\n                return _instance;\n            \n            _instance = new MyClass();\n            return _instance;\n        }\n    }\n}\n```\n\n```cs\npublic class MyClass\n{\n    private static MyClass _instance;\n\n    public static MyClass Instance =\u003e _instance??=new MyClass();\n}\n```\n\n## Fix/Mitigation\n\nUse a IoC/DI framework instead, or at least use proper locking when initializing the instance.\n\n## See also\n\n- [Singletons Are Evil](https://wiki.c2.com/?SingletonsAreEvil)\n- [Singleton Pattern](https://en.wikipedia.org/wiki/Singleton_pattern)\n\n## Rule configuration\n\nIn order to change the severity level of this rule, change/add this line in the `.editorconfig` file:\n\n```\n# DSA011: Avoid lazily initialized, self-contained, static singleton properties\ndotnet_diagnostic.DSA011.severity = warning\n```\n\n---\n\n# Installation\n\nJust download and install the NuGet package  \n[![DogmaSolutions.Analyzers on NuGet](https://img.shields.io/nuget/v/DogmaSolutions.Analyzers.svg)](https://www.nuget.org/packages/DogmaSolutions.Analyzers/)\n\n[https://www.nuget.org/packages/DogmaSolutions.Analyzers](https://www.nuget.org/packages/DogmaSolutions.Analyzers)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdogmasolutions%2Fanalyzers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdogmasolutions%2Fanalyzers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdogmasolutions%2Fanalyzers/lists"}