🔥 Most .NET developers get this wrong — DI Lifetimes explained! Picking the wrong lifetime = memory leaks, shared state bugs & hours of debugging. Here's the complete guide 👇 ♾️ Singleton ✅ Created ONCE — lives for the entire app lifetime ✅ Same instance shared across ALL requests & threads ✅ Best for: IConfiguration, IMemoryCache, ILogger ⚠️ Must be thread-safe — never store request-specific data ⚠️ Never inject Scoped or Transient services into Singleton! 🔄 Scoped ✅ Created ONCE per HTTP request ✅ Same instance shared within that single request ✅ Best for: DbContext, Repositories, Unit of Work ⚠️ Disposed automatically when the request ends ⚠️ Never use inside background services without IServiceScopeFactory ⚡ Transient ✅ Brand new instance created every single injection ✅ Never shared — always fresh, always isolated ✅ Best for: EmailSender, Validators, AutoMapper profiles ⚠️ Highest memory allocation — avoid for heavy objects ⚠️ Can be injected safely into any other lifetime 💡 Golden Rule: → Singleton → Stateless shared infrastructure → Scoped → Anything touching the database → Transient → Lightweight stateless helpers ⚠️ The #1 mistake I see: Injecting a Scoped DbContext into a Singleton service — your DbContext gets captured forever, causing data corruption & memory leaks! 📌 Save this — you'll need it in your next code review! 👇 Which lifetime do you misuse most? Drop it in the comments! #dotnet #csharp #aspnetcore #dependencyinjection #backend #cleancode #softwaredeveloper #programming #webdevelopment #dotnetcore #100daysofcode #softwareengineering
DI Lifetimes Explained: Singleton, Scoped, Transient
More Relevant Posts
-
💡 Dependency Injection in .NET - Where Most Developers Go Wrong In .NET Core, using Dependency Injection is easy. Understanding it properly is not. Most developers think DI means constructor injection: Inject the interface Register it in Program.cs Done But real backend engineering starts when you ask: 🔹 What should be Scoped, Transient, or Singleton? 🔹 What happens if a Singleton depends on a Scoped service? 🔹 Are you unintentionally sharing state across requests? 🔹 Is your service holding unnecessary dependencies? Here’s what I’ve observed: ⚠️ Making everything Scoped “just to be safe” ⚠️ Using Singleton for services that depend on DbContext ⚠️ Injecting 6–8 services into one class (SRP violation) ⚠️ Not understanding how lifetimes affect memory and threading In high-traffic systems, wrong lifetime configuration can cause: Memory retention issues Data inconsistency bugs Concurrency problems Hard-to-reproduce production failures Dependency Injection is not just a pattern. It’s an application lifecycle management strategy. When you truly understand lifetimes, your architecture becomes: ✔ More predictable ✔ More testable ✔ More scalable This is one of those topics interviewers love to go deep into especially with real-world scenarios. Next, I’m thinking of writing about common mistakes in Middleware ordering and request pipeline behavior. What topic should I break down next? #dotnet #aspnetcore #backend #softwarearchitecture #csharp
To view or add a comment, sign in
-
Managed vs Unmanaged Code in .NET: Understanding the Difference Most developers encounter these terms, but few truly grasp the difference. Let’s break it down: Managed Code: - This is the code you write in C# that runs under the control of .NET. - Runs inside the CLR (Common Language Runtime). - Memory is handled by the Garbage Collector (GC). - Safer and easier to manage with less risk of memory leaks. - You focus on logic, while .NET handles memory. Unmanaged Code: - This code runs outside the CLR. - No automatic memory management; you are responsible for allocation and cleanup. - Typically used for low-level operations, such as: - Native C/C++ libraries - OS-level APIs - Interop (P/Invoke) - Offers more control but comes with greater responsibility. The Real Difference: - Managed: Safe, controlled, automatic. - Unmanaged: Powerful, manual, risky. Why This Matters: Even in .NET applications, you often interact with unmanaged resources like file handles, database connections, and external libraries. This is why concepts like Dispose exist. Simple Takeaway: Managed code simplifies development, while unmanaged code provides deeper control. Great developers know when to stay managed and when to step outside it. #CSharp #DotNet #ManagedCode #UnmanagedCode #CLR #MemoryManagement #SoftwareEngineering #BackendDevelopment #DeveloperLearning
To view or add a comment, sign in
-
🚀 Are You Really Using Attributes in C# .NET Core Effectively? Most developers use attributes… but very few truly understand their power. Attributes in C# are not just decorative annotations — they are metadata-driven behavior controllers that can completely change how your application behaves without touching core logic. 💡 What Are Attributes? Attributes in C# .NET Core are special tags that you apply to classes, methods, properties, or parameters to add declarative information. This information can then be read at runtime (via reflection) or used by the framework to modify behavior. 🔍 Why Attributes Matter (Real Impact) Think about this: Instead of writing repetitive logic for: • Authorization checks • Validation rules • Logging • API behavior You simply declare it once using attributes. And the framework does the rest. ⚙️ Real-World Examples ✔️ Security [Authorize(Roles = "Admin")] → Restricts access without writing manual checks ✔️ Validation [Required], [MaxLength(50)] → Automatically validates incoming data ✔️ Deprecation [Obsolete("Use NewMethod")] → Warns developers at compile time ✔️ Routing & APIs [HttpGet], [Route("api/products")] → Controls API behavior cleanly 🧠 Why Senior Developers Love Attributes Because they: ✅ Reduce boilerplate code ✅ Improve readability (intent is clear) ✅ Enable separation of concerns ✅ Make code more maintainable ✅ Integrate deeply with ASP.NET Core pipeline 🔥 Key Insight “Attributes shift your code from how things work to what should happen.” That’s a massive mindset shift — and a hallmark of clean architecture. 📌 When Should You Use Attributes? Use them when you want to: • Declare behavior instead of implementing it repeatedly • Plug into framework-level features • Keep your business logic clean and focused If you’re building scalable .NET applications, mastering attributes is not optional — it’s essential. 💬 Curious to go deeper into how reflection powers attributes internally? Let’s discuss. #DotNet #CSharp #SoftwareEngineering #CleanCode #BackendDevelopment #ASPNetCore
To view or add a comment, sign in
-
-
Singleton vs Scoped vs Transient in .NET Core — get this wrong and you'll have bugs that only appear in production. This is the #1 concept every .NET developer must understand cold. SINGLETON → Created once when the app starts → Same instance shared across ALL requests, ALL users, ALL threads → Lives until the app shuts down → Use for: logging, caching, config, HttpClientFactory Never inject a Scoped service inside a Singleton — Captive Dependency bug SCOPED → New instance created per HTTP request → Shared within the same request, but separate across different requests → Disposed when the request ends → Use for: DbContext, repositories, Unit of Work This is what EF Core's DbContext was designed for TRANSIENT → Brand new instance every single time it's injected → Never shared with anything → Use for: lightweight stateless services, validators, formatters Don't use for heavy services — memory pressure in prod The 3 mistakes I've seen in real codebases: Singleton DbContext → shared across all users = data corruption + threading bugs Singleton injecting Scoped → captive dependency, scoped service never disposed Transient for DB connections → new connection every call = memory leak The simple rule: Singleton = stateless, shared, thread-safe Scoped = anything tied to a single request Transient = lightweight, stateless, disposable I've been working with .NET Core daily building enterprise APIs — wrong DI lifetime is one of the sneakiest production bugs you can ship. Which one trips up your team the most? #DotNetCore #CSharp #BackendDevelopment #SoftwareEngineering #FullStackDeveloper #DependencyInjection #AspNetCore #DotNet
To view or add a comment, sign in
-
-
Is the Repository Pattern Dead in .NET 10? 🛠️ I’ve been seeing a lot of debate lately. With Entity Framework Core evolving so rapidly through .NET 8, 9, and now .NET 10, many developers are asking: Do we still need an abstraction over an abstraction? The answer isn't a simple yes or no—it’s about Transaction Management and maintainability. In my latest ASP.NET Core tutorial (Part 1), I break down why the Unit of Work pattern and the Generic Repository are still my "go-to" for complex enterprise applications. If you’ve ever struggled with keeping your business logic clean or managing multiple DB changes in a single atomic transaction, this is for you. What we’re covering in this .NET tutorial: 1. Implementing a robust Unit of Work in ASP.NET Core. 2. Creating a reusable Generic Repository that doesn't bloat your code. 3. Bridging the gap between Entity Framework Core and clean architecture. 4. The evolution of the Repository Pattern in C# from .NET 7 all the way to .NET 10. Stop writing "leaky" abstractions and start mastering Unit of Work Entity Framework Core patterns that actually scale. Let's Learn How to Implement : https://lnkd.in/g85shcyn What’s your take? Do you prefer the "Thin Controller + DBContext" approach, or are you Team Repository Pattern? Let’s discuss in the comments! 👇 #DotNet #AspNetCore #CSharp #SoftwareArchitecture #EFCore #Programming #WebDev #UnitOfWork #RepositoryPattern
To view or add a comment, sign in
-
-
🚨 7 Common Mistakes .NET Developers Make (And How to Avoid Them) After working on multiple .NET projects, I’ve noticed many developers make the same mistakes again and again. Avoiding these can instantly improve your code quality and performance. 🔹 1. Not Using Async/Await Properly Blocking calls like .Result or .Wait() can cause deadlocks and performance issues. 🔹 2. Writing Very Large Controllers Controllers should be thin. Business logic should be in services or application layer. 🔹 3. Not Using Dependency Injection Properly Avoid creating objects with new everywhere. Use DI container and interfaces. 🔹 4. Poor Entity Framework Queries Common mistakes: • Not using AsNoTracking() • Selecting entire entities instead of specific fields • Missing indexes in database 🔹 5. No Logging Every production app should have logging (Serilog / NLog / built-in logging). 🔹 6. No Exception Handling Strategy Use global exception middleware instead of try/catch everywhere. 🔹 7. Ignoring Database Design Bad database design can destroy performance, even if your code is good. ⸻ 💡 Simple Rule: Good code can’t save a bad database design, but a good database can save bad code. ⸻ 📱 Side Project I Built: I built HisabDo – Expense Management App to track daily expenses and manage accounts easily for freelancers and small businesses. If you want to try it: https://lnkd.in/dgMZh97a ⸻ 💬 What is the most common mistake you see developers making? #DotNet #CSharp #ASPNetCore #SoftwareEngineering #CleanCode #Developers #EntityFramework #Programming #DotNetDeveloper #Tech
To view or add a comment, sign in
-
-
In one of my recent projects, there was an app which was failing in production randomly. But it was dying consistently. Users were not able to launch their clients - "No active Server found". Existing clients were hung. The silver bullet ops used - server restart. Everything smooth. Then after a few weeks, same issue. The story repeated. Logs showed no errors. Heap dumps, thread dumps, memory, CPU - everything was looked at. No exceptions, no spikes, no BLOCKED threads. One expert suggested moving from 8GB to 20GB heap. But there was no OutOfMemoryException either. Nothing was moving. Until I kept looking for signals. The thread dumps finally showed something. All worker threads were in a RUNNING state - which was an illusion. They were actually stuck executing an external Perl script. The script was hitting database errors. But the real problem was the Java code handling it. When Java calls an external script, it communicates through two streams - STDOUT and STDERR. The code was reading them one at a time. STDOUT first, then STDERR. Meanwhile the script was writing errors to STDERR. Nobody was reading it. The pipe filled up. The script got stuck. Because it got stuck, STDOUT never closed. Because STDOUT never closed, the Java thread waited forever. One worker swallowed. Then another. Then another. Until there were no workers left. "No active server found." --- The code did have a timeout mechanism - a timer thread that would interrupt the stuck worker after 5 minutes. It looked like a safety net. It was an illusion. Thread interrupts only work on BLOCKED or WAITING threads. A thread stuck in native I/O appears RUNNING - interrupts don't reach it. The timer fired. The worker ignored it. The safety net had a hole nobody could see. --- The fix - drain STDOUT and STDERR concurrently using dedicated "gobbler" threads so neither pipe fills up. Add a process-level timeout that terminates the script itself. --- This had been repeating for months. A safety mechanism that gave everyone confidence - but didn't actually work. Small assumptions. Big consequences. Sometimes the most important thing you can do is refuse to accept "restart and move on" as an answer. --- Have you ever come across a problem that was hiding in plain sight? #SoftwareEngineering #Java #ProductionEngineering #LessonsLearned #TechLeadership #ProblemSolving
To view or add a comment, sign in
-
💡 IDisposable & the using statement: Every .NET developer writes using daily. But do you actually know what’s happening under the hood? 🔷 WHAT is IDisposable? IDisposable is an interface with a single method: Dispose(). When you implement it, you’re telling .NET: “This object holds resources that need manual cleanup.” These resources can be: → File handles → Database connections → Network streams → Unmanaged memory The GC handles memory, but it doesn’t know about these external resources. That part is your responsibility. 🔷 WHY does it matter? The GC is great, but it’s intentionally lazy. It runs when it decides to run, not when your application immediately needs cleanup. Without Dispose(): → your connection may stay open → your file may remain locked → your stream may continue living In high-load applications, this quickly turns into a resource leak problem. IDisposable gives you full control over deterministic cleanup. 🔷 WHEN should you use using? The using statement guarantees Dispose() gets called, even if an exception happens. Modern C# makes it even cleaner: using var conn = new SqlConnection(connStr); At the end of the scope, cleanup happens automatically. Use using whenever you work with: → SqlConnection, StreamReader, FileStream → DbContext in non-DI scenarios → anything implementing IDisposable Tip most developers miss: When implementing IDisposable yourself, always call: GC.SuppressFinalize(this); This tells the GC: “Cleanup is already done — skip finalization.” That prevents a second cleanup pass and reduces unnecessary finalizer overhead. Most developers skip this. Don’t be most developers. 🔑 Key difference IDisposable → signals that manual cleanup is required using → guarantees that cleanup happens GC.SuppressFinalize → prevents duplicate cleanup The using statement is your safety net. IDisposable is the contract. Together, they keep your application leak-free and production-safe. Drop a comment below. #dotnet #csharp #dotnetdeveloper #softwareengineering #softwaredevelopment #cleancode #backenddevelopment #webapi #aspnetcore #entityframework #developer #programming #coding #techlead #architecture #bestpractices
To view or add a comment, sign in
-
-
Whenever I create a class in C#, I always use IDispoable. This way, I can use using statement to create a new instance of my class and using will ensure the dispose method gets called removing any objects I used in the class gets destroyed properly. This will prevent memory leaks.
💡 IDisposable & the using statement: Every .NET developer writes using daily. But do you actually know what’s happening under the hood? 🔷 WHAT is IDisposable? IDisposable is an interface with a single method: Dispose(). When you implement it, you’re telling .NET: “This object holds resources that need manual cleanup.” These resources can be: → File handles → Database connections → Network streams → Unmanaged memory The GC handles memory, but it doesn’t know about these external resources. That part is your responsibility. 🔷 WHY does it matter? The GC is great, but it’s intentionally lazy. It runs when it decides to run, not when your application immediately needs cleanup. Without Dispose(): → your connection may stay open → your file may remain locked → your stream may continue living In high-load applications, this quickly turns into a resource leak problem. IDisposable gives you full control over deterministic cleanup. 🔷 WHEN should you use using? The using statement guarantees Dispose() gets called, even if an exception happens. Modern C# makes it even cleaner: using var conn = new SqlConnection(connStr); At the end of the scope, cleanup happens automatically. Use using whenever you work with: → SqlConnection, StreamReader, FileStream → DbContext in non-DI scenarios → anything implementing IDisposable Tip most developers miss: When implementing IDisposable yourself, always call: GC.SuppressFinalize(this); This tells the GC: “Cleanup is already done — skip finalization.” That prevents a second cleanup pass and reduces unnecessary finalizer overhead. Most developers skip this. Don’t be most developers. 🔑 Key difference IDisposable → signals that manual cleanup is required using → guarantees that cleanup happens GC.SuppressFinalize → prevents duplicate cleanup The using statement is your safety net. IDisposable is the contract. Together, they keep your application leak-free and production-safe. Drop a comment below. #dotnet #csharp #dotnetdeveloper #softwareengineering #softwaredevelopment #cleancode #backenddevelopment #webapi #aspnetcore #entityframework #developer #programming #coding #techlead #architecture #bestpractices
To view or add a comment, sign in
-
-
Most .NET developers use Dependency Injection every day. But not everyone knows why it actually matters. Let me break it down simply. 👇 What is DI? Instead of a class creating its own dependencies, they get injected from the outside. ❌ Without DI: public class OrderService { private readonly EmailService _email = new EmailService(); } ✅ With DI: public class OrderService { private readonly IEmailService _email; public OrderService(IEmailService email) { _email = email; } } Looks like a small change. The impact is huge. 3 reasons DI makes your .NET code better: 1. Testability You can swap real services with mocks in unit tests — no need to touch production code. 2. Loose Coupling Your classes depend on interfaces, not concrete implementations. Change the implementation, nothing breaks. 3. Lifetime Management .NET handles when objects are created and destroyed for you — Singleton, Scoped, Transient. No manual newing up everywhere. Quick reminder on lifetimes: Singleton → one instance for the entire app Scoped → one instance per HTTP request Transient → new instance every time it's requested DI isn't just a pattern. It's the backbone of clean, maintainable .NET architecture. If you're still manually instantiating dependencies — it's time to let .NET do the heavy lifting. Hashtags: #dotNET #CSharp #DependencyInjection #SoftwareEngineering #CleanCode #BackendDevelopment #AspNetCore
To view or add a comment, sign in
-
More from this author
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development
👍