lazy Initialization - Delay Object Creation, leading to Dependency Injection, DI
- Renee Li
- Oct 25
- 3 min read
The code that me and Copilot vibe coded - see this blog for code. It got me thinking.
It is quite distinct and unlike anything I've learned before. In most classes within this design, creating an object isn't necessary until the final step, which helps lower runtime costs. I asked ChatGPT the reason for this.
Excellent observation — you’re noticing a subtle but important design pattern trend in modern enterprise C# and .NET systems. Let’s break this down clearly:
🧩 What You’re Seeing
Yes — many enterprise-grade C# architectures (especially in ASP.NET Core, DDD, or Clean Architecture projects) often:
Don’t explicitly define constructors in many classes.
Delay object creation until the “composition root” (usually the Startup.cs, Program.cs, or a dependency injection container).
Prefer dependency injection (DI), lazy initialization, and factory patterns to control when and how objects are instantiated.
⚙️ Why Enterprises Prefer This
1. Performance & Memory Efficiency
Creating objects only once (e.g., Singleton or Scoped lifetime) avoids repeated heap allocations.
DI frameworks manage object reuse and disposal, optimizing runtime performance.
2. Maintainability & Testability
Classes with no hardcoded constructors or dependencies are easier to mock and test.
You can swap implementations (e.g., IEmailService → MockEmailService) without touching business logic.
3. Separation of Concerns
Object creation is centralized in the composition root — keeping business logic clean.
The creation logic (factories, DI container) is separated from object usage.
4. Runtime Cost Reduction
Especially in high-traffic systems (web APIs, microservices), avoiding unnecessary instantiation reduces GC pressure and startup time.
🏢 Common Patterns in Modern C# Enterprises
Pattern | Purpose | Example |
Dependency Injection (DI) | Centralized object creation | services.AddScoped<IRepo, Repo>(); |
Factory Pattern | Deferred or dynamic creation | UserFactory.Create(type) |
Singleton | Reuse same instance | services.AddSingleton<CacheManager>(); |
Lazy<T> | Create only when needed | new Lazy<ExpensiveService>(() => new ExpensiveService()) |
Record/Static Utility Classes | No need for constructors | public static class MathUtils |
⚖️ Trade-offs
Pros:
Faster runtime (less object churn)
Easier testing and swapping dependencies
More modular architecture
Cons:
Slightly more complex setup (especially DI)
Harder to trace object creation for beginners
Over-engineering for small projects
🧠 Summary
✅ Yes — enterprises today (especially .NET 6/7/8 and cloud-native apps) prefer constructor-minimal, dependency-injected, factory-driven designs.They create objects only once at the application’s entry point and pass them around — improving both runtime performance and maintainability.
As a student, I am just really glad I saw this today, and now I can relate to once someone said to me. Once an computer networking engineer told me not to worry too much about TCP and what am I learning in uni now. Chances is what I learnt uni now might be very different from what I will apply after I join a company. I was not fully understand what he said until now.
In university, I was told to put constructor in classes that I write, which makes sense to me. But in Uni assignment, bank class which is the orchestral class, did not need a constructor. But I did not think too much back then. Now, with more understanding of Azure and cloud computing and run time cost and so on, I start to understand what the computer networking engineer told me and I guess university was not wrong. They just did not want to make things more complicated for us. But, in real work production, cost reduction and profit maximization are always priority for companies.
From now on, when I design a program, I will always ask myself to think from a company owner prospective as if my design is the most cost-effective way?
At some point, I need to get to know about Dependency Injection, DI, as well. Apparently, that's what developers in real work situation use in design enterprise-level C# programs.



Comments