Milan Jovanović

17.5K posts

Milan Jovanović banner
Milan Jovanović

Milan Jovanović

@mjovanovictech

I make .NET content

Katılım Haziran 2022
772 Takip Edilen47.8K Takipçiler
Sabitlenmiş Tweet
Milan Jovanović
Milan Jovanović@mjovanovictech·
Stop wasting the first 3 days of every project setting up boilerplate. I built a free, production-ready Clean Architecture template to handle the setup for you. It's already used by 40,000+ developers. Here is what's inside the latest version: - 𝗨𝗽𝗱𝗮𝘁𝗲𝗱 𝘁𝗼 .𝗡𝗘𝗧 𝟭𝟬 - 𝗡𝗲𝘄 .𝘀𝗹𝗻𝘅 𝗦𝗼𝗹𝘂𝘁𝗶𝗼𝗻 𝗙𝗼𝗿𝗺𝗮𝘁 - CQRS (no MediatR dependency) - Structured Logging & Validation - JWT Authentication & RBAC - Docker Compose support It saves you hours of setup time. Download it for free here: milanjovanovic.tech/templates/clea… 💡 Why the shift to .slnx? The new Solution format in .NET is a game-changer. It replaces the old bloated syntax with a clean XML syntax. It makes merge conflicts in your solution file a thing of the past.
Milan Jovanović tweet media
English
3
12
88
7.1K
Milan Jovanović
Milan Jovanović@mjovanovictech·
This code works perfectly... Until two users try to register with the exact same email at the exact same time. 💥 Without a database rule, both users slip right through. This is a classic race condition. You could lock the process in your code. But that slows down your entire app for everyone else. The better fix? Let the database do the heavy lifting: 1️⃣ Add a unique constraint (or index) to your email column. 2️⃣ Let the database automatically block the duplicate. 3️⃣ Catch that specific error cleanly in your .NET app and show a friendly message. It’s simple, reliable, and scales without killing your performance. Want to see exactly how to implement this? Check out my full breakdown here: milanjovanovic.tech/blog/solving-r… How do you usually handle duplicate data like this? Let me know below! 👇 --- Tired of writing the same boilerplate code for every new project? Skip the setup and start building features immediately with my Clean Architecture template: milanjovanovic.tech/templates/clea…
Milan Jovanović tweet media
English
2
0
8
412
Dr Milan Milanović
Dr Milan Milanović@milan_milanovic·
What is LinkedIn today...unfortunately We cannot even be genuine when adding comments in a discussion
Dr Milan Milanović tweet media
English
2
0
6
1.6K
Milan Jovanović retweetledi
Milan Jovanović
Milan Jovanović@mjovanovictech·
What's wrong with the first code snippet? The second example is 43x faster to insert 10,000 records. But what causes such a huge performance difference? If you understand how EF works under the hood, the answer should be obvious. 👇
Milan Jovanović tweet media
English
7
12
73
6.8K
Milan Jovanović
Milan Jovanović@mjovanovictech·
A big advantage of Vertical Slice Architecture is that all the files related to one feature are close together. If you want to change that feature, you need to touch only one place in the codebase. The cohesion for a single feature is very high, which simplifies development.
Milan Jovanović tweet media
English
1
6
43
2.8K
Stefan Đokić | .NET
Stefan Đokić | .NET@TheCodeMan__·
The problem isn’t your AI agent. It’s the missing plan. I’ve seen this pattern too many times lately: You open Cursor / Claude / Copilot… Start generating code… And then: • prompts keep changing • output gets messy • you waste tokens • PR turns into a battlefield Not because AI is bad. But because there was no clear plan from the start. That’s why this new release from @coderabbitai caught my attention (sponsored). They just introduced CodeRabbit Plan. And the idea is simple, but powerful: 👉 Move the discussion from PR → to before any code is written Instead of: Build → PR → Debate → Rewrite You get: Plan → Align → Build Here’s how it works: You describe what you want to build (+ attach PRDs, designs, docs, context) ↓ It generates a structured, implementation-ready plan ↓ Your team (or you solo) aligns on it ↓ Then you build with confidence What I liked in practice: • It generates high-quality, context-aware prompts for coding agents • Helps avoid “AI slop” and random iterations • Saves tokens (less trial & error loops) • Keeps PRs focused on validation, not architecture debates And combined with their AI code reviews: You’re basically covering both sides: ✔ Plan before writing code ✔ Review while writing code The biggest shift for me: Good code doesn’t start with coding. It starts with clarity. If you're working with AI agents or in teams where PRs turn into redesign sessions… This is worth checking out: 👉fandf.co/4uzARyL Thanks to CodeRabbit for sponsoring this post.
Stefan Đokić | .NET tweet media
English
4
4
29
1K
Milan Jovanović
Milan Jovanović@mjovanovictech·
Don’t start with microservices. ❌ Even if you think you'll need them later. Microservices come with a heavy tax: • More moving parts to coordinate • More ways for things to break • Complicated deployments • Higher infrastructure costs • Dealing with out-of-sync data None of this helps you ship faster early on. If you can’t build a clean monolith, microservices won’t save you. They’ll just multiply your mess. Do this instead: 1️⃣ Start with a modular monolith. 2️⃣ Let clear boundaries emerge naturally. 3️⃣ Split into separate services later (only if you have to). Your architecture should evolve with your product, not the other way around. Want to see how this works in practice? Read my full guide on building modular monoliths in .NET here: milanjovanovic.tech/blog/what-is-a… Would you start a brand new project with microservices today? Let me know why or why not below! 👇 --- P.S. If you want to master the Modular Monolith Architecture, start here: milanjovanovic.tech/modular-monoli…
Milan Jovanović tweet media
English
2
22
73
3.1K
Milan Jovanović
Milan Jovanović@mjovanovictech·
Every call to SaveChanges means one roundtrip to the database. In the first example, inserting each record means one call to the database. This quickly adds up... Here's why it's important to use the right tool for the job: milanjovanovic.tech/blog/fast-sql-…
English
1
0
10
844
Milan Jovanović
Milan Jovanović@mjovanovictech·
@AntonMartyniuk "Apply filters early to reduce the dataset size as quickly as possible." - this is something you probably don't have to think about as much. The query planner takes care of it for you.
English
1
0
1
197
Anton Martyniuk
Anton Martyniuk@AntonMartyniuk·
𝗦𝗲𝗰𝗿𝗲𝘁𝘀 𝘁𝗼 𝗢𝗽𝘁𝗶𝗺𝗶𝘇𝗶𝗻𝗴 𝗦𝗤𝗟 𝗤𝘂𝗲𝗿𝗶𝗲𝘀 Here are 20 proven techniques I use regularly to optimize SQL queries: ✅ Use Indexes Wisely: Index critical columns used in WHERE, JOIN, ORDER BY, and GROUP BY clauses. ✅ Avoid SELECT *: Fetch only the columns you need to minimize data transfer and processing time. ✅ Implement Pagination Properly: Use OFFSET and FETCH NEXT or seek-method pagination for efficient result paging. ✅ Limit Rows Early: Apply filters early to reduce the dataset size as quickly as possible. ✅ Avoid Functions in WHERE: Functions on columns prevent index usage; rewrite conditions to use raw columns. ✅ Reduce JOIN Complexity: Minimize the number of joins and avoid redundant joins wherever possible. ✅ Choose Correct JOIN Types: Use INNER JOIN, LEFT JOIN, or EXISTS appropriately to avoid unnecessary data processing. ✅ Use Proper Data Types: Match column data types exactly in JOIN and WHERE clauses to utilize indexes effectively. ✅ Query Only What Changed: Implement incremental data processing rather than repeatedly querying entire tables. ✅ Batch Operations: Group inserts, updates, or deletes to reduce transaction overhead. ✅ Eliminate Redundant Subqueries: Use joins or common table expressions (CTEs) instead of repetitive subqueries. ✅ Use EXISTS Instead of IN: The EXISTS clause often performs better than IN with large datasets. ✅ Normalize Wisely: Balance normalization with denormalization for performance-critical queries. ✅ Use Materialized Views: Pre-calculate complex aggregations and queries to speed up read operations. ✅ Analyze Execution Plans: Regularly check query execution plans to spot and optimize costly operations. ✅ Avoid Wildcards at Start: LIKE conditions with leading wildcards (%abc) prevent efficient indexing. ✅ Keep Transactions Short: Minimize transaction duration to reduce locking and contention. ✅ Update Statistics Regularly: Keep database statistics current to ensure accurate query planning by the DB engine. ✅ Use Query Hints Sparingly: Only use query hints after thorough testing and when necessary for specific optimizations. ✅ Monitor and Tune Continuously: Regularly monitor query performance and proactively tune slow queries. Optimizing SQL queries is part art, part science — but it always pays off. How do you optimize your SQL queries? Let's discuss 👇 📌 Save this post for future reference! — ♻️ Repost to help others optimize their SQL queries ➕ Follow me ( @AntonMartyniuk ) to improve your .NET and Database Skills
Anton Martyniuk tweet mediaAnton Martyniuk tweet mediaAnton Martyniuk tweet mediaAnton Martyniuk tweet media
English
5
24
133
5K
Milan Jovanović
Milan Jovanović@mjovanovictech·
A lot of developers still think of Redis as "just a cache". That undersells it, especially for AI integrations. What makes Redis useful in AI is the same thing that made it useful in distributed systems for years: It protects your hot path. Once you add AI features to an application, new problems show up very quickly: - Every request wants more context - Some requests are semantically similar - Repeated model calls get expensive - Latency becomes much harder to control - Your primary database starts handling work it was never meant to optimize for This is where Redis gets interesting. Redis can already sit on the hot path of a system with very low-latency reads and writes. On top of that, Redis now supports vector search, metadata filtering, semantic caching, and AI memory patterns. That makes it useful for much more than caching: - Retrieval for RAG - Semantic search - Conversation/session memory - Semantically similar response reuse - Low-latency context access before a model call If you’re building in .NET, this matters. That’s also why RedisVL caught my attention. RedisVL is Redis’s Python library for AI workloads. It gives you higher-level building blocks for things like vector search, semantic caching, and memory, instead of forcing you to stitch everything together from scratch. Yes, RedisVL itself is Python-first. But the bigger idea applies well beyond Python: AI systems need more than model access. They need low-latency infrastructure around the model. I think more .NET teams are going to run into this over the next year. If you want to explore how Redis fits into AI systems, start here: fandf.co/4l3ZXBe A huge thank you to @Redisinc for collaborating with me on this post.
Milan Jovanović tweet media
English
3
7
51
2.4K
Milan Jovanović
Milan Jovanović@mjovanovictech·
Here's my approach to CQRS. 👇 You can implement this as a vertical slice or between layers in Clean Architecture. I often use SQL for queries, but you can also go with EF Core directly. The important part is organizing the application around (business) use cases.
Milan Jovanović tweet media
English
2
31
138
8.5K
Anton Martyniuk
Anton Martyniuk@AntonMartyniuk·
𝗖# 𝗱𝗲𝘃𝗲𝗹𝗼𝗽𝗲𝗿𝘀 𝘄𝗮𝗶𝘁𝗲𝗱 𝟱 𝘆𝗲𝗮𝗿𝘀 𝗳𝗼𝗿 𝘁𝗵𝗶𝘀 𝗳𝗲𝗮𝘁𝘂𝗿𝗲 Discriminated unions were merged in .NET 11 Preview 3 Discriminated Unions are finally here. This is the #1 most requested C# language feature. And it changes how you model results, errors, and state - forever. Before unions, returning multiple outcomes from a method was painful. Here is what most developers did: ❌ Threw exceptions for control flow → expensive and hidden ❌ Returned nullable types → no way to express "why" it failed ❌ Used boolean flags with nullable fields → invalid states everywhere ❌ Relied on third-party libraries → extra dependency ❌ Built own Result Types All of these approaches had one thing in common: ➡️ The compiler could not help you. If you forgot to handle a case - you found out at runtime. 📌 𝗖# 𝟭𝟱 𝗶𝗻𝘁𝗿𝗼𝗱𝘂𝗰𝗲𝘀 𝘁𝗵𝗲 "𝘂𝗻𝗶𝗼𝗻" 𝗸𝗲𝘆𝘄𝗼𝗿𝗱 Now you can define a type that holds exactly one of several possible types. The compiler knows the full set of options (some compiler features are still in progress). Here is what unions give you: 𝟭. 𝗖𝗹𝗼𝘀𝗲𝗱 𝘀𝗲𝘁 𝗼𝗳 𝗼𝘂𝘁𝗰𝗼𝗺𝗲𝘀 → a union can only be one of the declared types 𝟮. 𝗘𝘅𝗵𝗮𝘂𝘀𝘁𝗶𝘃𝗲 𝗽𝗮𝘁𝘁𝗲𝗿𝗻 𝗺𝗮𝘁𝗰𝗵𝗶𝗻𝗴 → the compiler warns you if a case is missing 𝟯. 𝗡𝗼 𝗱𝗲𝗳𝗮𝘂𝗹𝘁 𝗯𝗿𝗮𝗻𝗰𝗵 𝗻𝗲𝗲𝗱𝗲𝗱 → when all cases are handled, you are done 𝟰. 𝗜𝗺𝗽𝗹𝗶𝗰𝗶𝘁 𝗰𝗼𝗻𝘃𝗲𝗿𝘀𝗶𝗼𝗻𝘀 → assign case types directly to the union variable 𝟱. 𝗩𝗶𝘀𝗶𝗯𝗹𝗲 𝗰𝗼𝗻𝘁𝗿𝗮𝗰𝘁𝘀 → the method signature tells the full story This is a massive shift in how we write C# code. Unions work beautifully with pattern matching and switch expressions that C# already has. In future .NET preview releases, we expect more features for discriminated unions and their official support in ASP .NET Core. 👉 If you want to be up to date with the latest .NET features and reach the top 1% of .NET developers, join 24,000+ engineers reading my .NET Newsletter: antondevtips.com/?utm_source=tw… —— ♻️ Repost to help other .NET developers discover discriminated unions ➕ Follow me ( @AntonMartyniuk ) to improve your .NET and Architecture Skills
Anton Martyniuk tweet mediaAnton Martyniuk tweet mediaAnton Martyniuk tweet mediaAnton Martyniuk tweet media
English
12
30
231
11K
LucasH Sketch
LucasH Sketch@dibujoslucas·
@mjovanovictech modular monoliths: what you actually need vs what sounds cooler in job interviews
English
1
0
1
60
Milan Jovanović
Milan Jovanović@mjovanovictech·
What is a Modular Monolith? It's an architectural pattern that structures the application into independent modules or components with well-defined boundaries. The modules are split based on logical boundaries, grouping together related functionalities.
Milan Jovanović tweet media
English
3
8
51
2.4K