C
C#2w ago
kyeeedeowo

.NET Best Practice on Architectural Design for a Multi-Solution Project

Hello everyone!! ^_^ I wanna mention that I've been a self-taught .NET developer for almost 10 years now, and I feel like my experience is slowly but surely paying off. A while ago, I decided to enable all analyzers across my solutions and treat warnings as errors in order to improve my code quality and ensure it follows .NET standards and best practices. However, after doing this, some parts of my codebase trigger certain warnings, including CA1515 warnings, which suggests that certain members should be marked internal rather than public. The issue is that my current architecture consists of multiple solutions that are separated for organizational purposes, and I need certain functions to remain accessible across these solutions. Because of that, simply making them internal would break access in other solutions. My questions are: 1. Is it practical to enable all analyzers and treat warnings as errors, or is that overkill for most real-world projects? 2. For the CA1515 scenario, what’s the recommended way to handle it when multiple solutions need to share access? Should I adjust the project structure, use InternalsVisibleTo, or just suppress the warning? 3. Are there situations where disabling or suppressing a warning is actually considered best practice? - How can you tell whether a warning is truly unresolvable and suppression is the right approach? - What criteria should I use to decide when to suppress instead of refactoring? My main goal is to write cleaner .NET code without introducing unnecessary friction into the development process. :lizardo: I appreciate everyone and truly do appreciate this community altogether for helping me throughout my code(s) in the past. Be harsh, don't hold back. Treat me like some intern that's about to get a reality check from a senior engineer who just :smh: at my code. (I haven't provided the code yet but if you'd like, let me know! ehe~)
9 Replies
kyeeedeowo
kyeeedeowoOP2w ago
I suppose I'll provide some code to help narrow down a solution. So, here is my current interface which is located in the Clyra.Abstractions solution:
using Clyra.Domain.Enums;

namespace Clyra.Abstractions.Services;

public interface ICharacterObfuscationProvider
{
CharacterObfuscation HandledFlag { get; }

string BuildObfuscatedFragment(char c);

bool CanHandle(char c);
}
using Clyra.Domain.Enums;

namespace Clyra.Abstractions.Services;

public interface ICharacterObfuscationProvider
{
CharacterObfuscation HandledFlag { get; }

string BuildObfuscatedFragment(char c);

bool CanHandle(char c);
}
So, the point of this interface is to implement an abstraction that other providers inherit. It is supposed to be a 'base' I suppose. Now, my problem is specifically CharacterObfuscation which is located in Clyra.Domain.Enums.
namespace Clyra.Domain.Enums;

[Flags]
public enum CharacterObfuscation
{
None = 0,
Homoglyphs = 1 << 0,
Diacritics = 1 << 1,
Emojis = 1 << 2,
Symbols = 1 << 3,
Numbers = 1 << 4,
Ascii = 1 << 5,
}
namespace Clyra.Domain.Enums;

[Flags]
public enum CharacterObfuscation
{
None = 0,
Homoglyphs = 1 << 0,
Diacritics = 1 << 1,
Emojis = 1 << 2,
Symbols = 1 << 3,
Numbers = 1 << 4,
Ascii = 1 << 5,
}
So, in a real world situation, would an engineer consider this a result of "code smell" and refactor it or would changing the modifier class to public and disregarding CA1515 be the most practical approach? Like sure, technical debt exists in almost every software project. It comes down to architectural design and patterns to address these issues in a clean way, rather than resorting to quick fixes or workarounds that might create even more problems later on. :Smadge:
ACiDCA7
ACiDCA72w ago
the thing about CA1515 is that it asumes that the class is in the "correct" project. but its more an indicatator that the class should be moved to a library that could be shared instead of having it in the executable the reason the warning pops up is because executables arent >usually< meant to have api to be called by other programs, therefore making it no sense having everything public.
ACiDCA7
ACiDCA72w ago
Is it practical to enable all analyzers and treat warnings as errors, or is that overkill for most real-world projects?
they are more of a starting point.. you can even confiugure if you want minimal, medium or all analyzer and then you can adjust with the editorconfig to your likinbg
For the CA1515 scenario, what’s the recommended way to handle it when multiple solutions need to share access? Should I adjust the project structure, use InternalsVisibleTo, or just suppress the warning?
a shared library, because CA1515 shouldnt pop up in libs
Are there situations where disabling or suppressing a warning is actually considered best practice?
sometimes you have no other choice than to supress the warning
kyeeedeowo
kyeeedeowoOP2w ago
Right, so in terms of my current design, it isn't technically incorrect but more-so I should utilize libraries as they are meant to be consumed, right?
ACiDCA7
ACiDCA72w ago
if you have stuff you want to share between projects definitly use libs
kyeeedeowo
kyeeedeowoOP2w ago
I see, I did check and my Abstractions solution is a web app. So that explains why. Ideally, the only part of solution that should be internal and an app is my main point Bot. Everything else depending on the use case should be a lib.
ACiDCA7
ACiDCA72w ago
"everything" sounds so absolute.. libs are there for code to be reused, if there is no need for reuse it can stay in executable and if it doesnt have to be reused you can use the analyzers to find unused code, but the analyzer only tells you if the code is unused if it isnt public
kyeeedeowo
kyeeedeowoOP2w ago
Aaaaa- Okay got it. Yes! So I checked out my solution's project sdk and it seems like it's all just Sdk.Web -w-. I think I may or may not have copied the csproj template into other whilst clearing my solution.
Clyra.Abstractions.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.Bot.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.Commands.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.Core.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.Domain.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.Infrastructure.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.Interactions.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.Modules.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.Rest.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.Shared.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.WebSocket.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.Abstractions.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.Bot.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.Commands.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.Core.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.Domain.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.Infrastructure.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.Interactions.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.Modules.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.Rest.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.Shared.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
Clyra.WebSocket.csproj: <Project Sdk="Microsoft.NET.Sdk.Web">
That explains why the CA1515 issues is appearing because my web application is the one triggering CA1515. :harold: Alright. I think I have at least a starting point on what to fix. Thank you so much! ^_^ Okay yeah I fixed it... -w- sometimes the easiest solution is somehow also the easiest to overlook. THANK U!

Did you find this page helpful?