
Explore why clean, maintainable code lowers overall software cost by reducing maintenance and understanding effort, and learn the meta principles behind clean coding practices.
Study the meta principles behind clean code in C#, including dry, kiss, yagni, separation of concerns, command query separation, least astonishment, and information hiding.
Master the dry principle to avoid duplication, replace magic values with meaningful constants, refactor duplicated logic into common methods, and apply the open-closed principle to replace switch cases.
Apply the kiss principle to keep software simple by reducing accidental complexity through decomposition and SOLID design, favoring composition over inheritance and avoiding premature optimization.
emphasizes the Yagni principle to avoid overengineering by implementing only what is needed now, weighing future costs such as delay and carry.
Apply separation of concerns to build modular systems by isolating ui, business logic, presentation, and database; avoid leaking abstractions and keep domain logic persistence agnostic for easier maintenance.
Explore the command query separation principle by Bertrand Meyer, ensuring methods are either commands or queries—not both—so APIs remain honest and easy to reason about.
Master the principle of least astonishment and its role in safe API design, avoiding temporal coupling, and ensuring predictable, expectation-driven behavior for users and clients.
Learn how encapsulation and information hiding protect invariants by exposing safe interfaces and hiding internal state. Use constructors, properties, and query methods to build robust, foolproof APIs.
Apply the dry principle to ensure a single unambiguous representation, avoiding magic strings and duplicate logic. Decompose to tame essential versus accidental complexity and uphold srp and soc with cqrs.
Learn general principles of naming in c# and dotnet, emphasizing readability, maintainability, and refactoring with modern tools for renaming variables and dependent declarations, as well as extracting classes and interfaces.
Choose intention revealing names that reflect the meaning of a member. Keep names aligned with scope, use verbs for functions, and nouns for classes to improve readability.
Use descriptive, action-oriented names for code elements, name buttons with verbs like generate report, avoid default button one, and choose meaningful class and method names to ensure readable prose.
Explore dot net naming conventions, using pascal casing for public members and camel casing for private fields and parameters, with optional underscore prefixes and acronym rules.
Apply general naming principles to write readable C# code with intention revealing names, using English terms and domain terms, and follow dotnet conventions for classes (nouns) and functions (verbs).
Master the art of writing clean code in C# by exploring clean functions, clean variable declarations, avoiding magic numbers, stringly typing, and refactoring techniques like extract method and guard clauses.
Discover why declaring variables at the top of methods can hinder readability and trigger context switching, and learn to place declarations near usage for cleaner code in C Sharp.
Identify magic numbers as a code smell and replace them with well named constants or an enumeration to improve readability and reduce complex conditional logic.
Explore the stringly typed code smell, learn why using string literals like red, yellow, green is error prone, and refactor into enums or strong abstractions to ensure type safety.
Explore when to implement a member as a property or a method, weighing parameter count, overloads, and optional parameters, and emphasize properties are simple, cohesive, and API friendly.
Learn parameter design practices in C#: choose specific types, avoid out/ref, validate with exceptions, prefer enums over booleans, refactor with a separate class to aggregate parameters, and use named parameters.
Limit function parameters to three and extract extras into a parameter object or class. Refactor into two methods or use a date range structure to improve readability and single responsibility.
Explore the pros and cons of long methods and the extract till you drop technique, balancing readability, maintenance, and SRP when refactoring large codebases.
compare constructors with factories in creational patterns, highlighting when factory use enhances application programming interface building, tool support, and fluent builder scenarios, while illustrating singletons and base type returns.
Explore extract method refactoring to replace a search with focused methods like get closest and calculate distance, convert the for loop to for each, and isolate pure logic for testability.
Explore determining overlapping ranges using a begin and end properties structure, noting non-inclusive ends, and refactor complex overlap logic by validating non-overlap cases for simpler, reliable comparisons.
Explore the sequence of arguments in if statements and methods, debunk yoda notation, and show how named parameters improve readability in c# unit tests and assertions.
Explore guard clauses and early returns to improve readability and reduce nesting, and evaluate single versus multiple return statements in clean code. Assess how null checks influence clean code.
Refactor complex conditionals by replacing them with ternary operators or switch statements to improve readability. Extract descriptive intermediary variables and well-named methods to centralize validation logic and boost maintainability.
Explore handling output parameters and the try pass pattern, refactoring to a dedicated class, and using a result monad or tuples to enable clean, error-aware pipelines in C-sharp seven.
Evaluate when to use comments and when to avoid them, refactor to self-explanatory methods, and use targeted comments to reveal concepts like the Eratosthenes sieve in prime generation.
Learn to improve code readability in C# by using affirmative boolean predicates instead of double negatives, and name booleans clearly.
Refactor code smell by turning magic numbers into constants, avoiding top-of-method declarations, and favor strong types over generic strings; use guard clauses, reduce long methods, and group parameters into classes.
Explore architectural design smells, including primitive obsession and temporal coupling, and apply the law of Demeter while refactoring switch statements with template method, strategy, and state patterns.
Transform primitive string representations into a dedicated zip code class to encapsulate validation and business rules, avoiding design smells and enabling casting and cleaner APIs.
Explore Demeter, a guideline for loose coupling. See how exposing a wallet breaks encapsulation in a paper boy scenario, and fix it by delegating payment to the customer.
Explore temporal coupling as a common API smell where a sequence of calls matters, and remove it by requiring necessary inputs in the constructor.
Refactor switch-heavy code using the template method design pattern with abstract classes and concrete models, embracing the open-closed principle and dictionary-based mappings.
Explore the strategy pattern, a behavioral design pattern that selects an algorithm at run time, decouples clients from algorithms, and uses dependency injection to delegate behavior through an interface.
Explore refactoring a nested switch on a turnstile into the state design pattern, with locked and unlocked states driven by coin and pass events and a transition table for maintainability.
Examine primitive obsession, showing why strings for zip codes create clutter and costs. Navigate demeter coupling, temporal coupling, and refactor switch statements with template method, dictionary, strategy, and state patterns.
Extend types to enable functional programming in C#, embracing immutability and pipelining while building practical extensions, including the IDisposable interface and StringBuilder.
Explore programming paradigms with a focus on functional programming, its immutability, and how C Sharp leverages generics, Linq, and method extensions in a multi-paradigm landscape.
Discover functional programming as a paradigm that treats computation as mathematical functions, avoids state changes, and relies on declarative expressions and independent, testable code.
Explore how objects drive object-oriented programming in C#, and how functions serve as first class citizens, guided by best practices, SOLID principles, and functional patterns.
Explore why learning functional programming matters, even from PHP ideas, to reduce code, enable composable, reusable components, and improve safety, immutability, no shared state, and concurrency safety.
Explore immutability as a core functional programming concept, show how returning new instances instead of mutating state improves readability and safety for concurrent access, and reduces temporal coupling.
Compare structures and classes, structures copy by value, classes by reference, and spot the risks of mutable structures. See a point struct that returns new instances to achieve true immutability.
Examine how temporal coupling arises from mutating state and how immutability and pure functions prevent it, with a refactor that removes shared state and reduces side effects.
Explore how pipelining passes the output of one function to the next to streamline data flow in C# via method chaining.
Explore extending IDisposable types to enable functional composition with using blocks, wrapping stream readers and a data parser to parse CSV data and map types while avoiding nulls.
Learn how general extensions in C# enable fluent call chains, type conversion, and predicate-driven processing to keep code readable and functional, from date time to device formats.
Refactor a procedural stringbuilder usage into extension methods, replacing append format and loops, with extensions handling validation and formatting and using string interpolation after C# six.
Expose primitive obsession and show how extension methods can encourage bad practice. Propose a money structure as a value object to represent currency safely.
Master the builder pattern for immutable objects and fluent APIs, demonstrated with a person class and a testable phone service built via unit tests with mocks and a dependency builder.
Explore why exceptions clash with functional programming and learn to replace out parameters with a result class that encodes success, error, and optional value, enabling safe pipelining.
Explore how to implement pipelining in C# through method chaining with a result class and extension methods, enabling clean, flat control flow for success and failure paths.
Explore functional programming techniques in C# to reduce code, improve immutability, and build composable, testable components; learn fluent APIs, extension patterns, and error handling with the result monad.
Explore common antipatterns and refactorings in dependency injection, including constructor over injection, ambient context, and service locator, and address cyclic dependencies with the factory pattern.
Identify and fix the control freak anti-pattern by moving payment method creation from the view model to a dedicated factory, enabling dependency injection, runtime selection, and abstract factory use.
Expose all dependencies in the public api to enforce the contract and prevent hidden preconditions, using the constructor so callers provide required instances and the compiler validates them.
Temporal coupling creates hidden interconnections in an API that require a specific call order. Enforce constructor injection, such as requiring a Uri, to eliminate this coupling and prevent invalid states.
This lecture examines constructor over-injection in viewmodels, arguing to hide infrastructural dependencies, use import attributes to move them out, and consider service locator pitfalls, with pragmatic refactorings in bootstrapper.
Use ambient context to provide access to utility dependencies like I progress event aggregator and I prompt creator, enabling unit testing and reducing constructor complexity for hundreds of view models.
Explore how a facade service encapsulates accounts receivable, irate exchange, and a user context, reinforcing the single responsibility principle and consolidating logic with an order collector interface.
Explore property injection as an alternative to constructor injection, define bastard injection, and examine how default constructors can create tight coupling across assemblies, with examples from dotnet framework and WPF.
Identify and break cyclic dependencies by inverting the cycle with events or callbacks, or introducing interfaces and an abstract factory to decouple components and avoid resolution errors.
Contrast control freak patterns with dependency injection and avoid the service locator anti-pattern. Note risks like many dependencies and temporal coupling, and embrace inversion of control for cleaner architecture.
Learn unit testing best practices in C#, examining how singletons and static classes hinder tests, the role of dependency injection, and single-concern approach to testing one unit at a time.
Examine how singletons and static classes introduce global dependencies that hinder unit testing, and how explicit initialization and constructor injection can improve testability and design.
Identify that interfaces with a single implementation signal a code smell and that interfaces are not abstractions, highlighting extract interface refactoring and its impact on testability.
Identify primitive obsession and model a four-part record (id, currency, pair rate, stamp) with readonly properties, then implement a file manager, persister, and quotation service with accompanying tests.
Explore the debate on testing trivial code in c#, including getters, setters, and one-line methods, through Uncle Bob and Mark Seeman's perspectives on tdd and engineering judgment.
Explore the rule of a single logical assertion in unit tests, clarifying when multiple assertions test the same aspect, with examples from a money class and currency properties.
Learn to write trustworthy, readable, and maintainable unit tests by avoiding control flow and duplication, avoiding multiple mocks, and avoiding ordered tests and over specification, with guidance on cleanup.
Explore clean code practices in C#, showing how singletons, static classes, and single interface implementation hinder tests, and how to test one logical unit per test with daily best practices.
Explain what tdd is and why we need it, cover red green refactor and the three laws, and show tdd in a tic tac toe game with roman numerals.
Drive production code with tests by writing unit tests first, shaping a modular, testable design, and achieving about 70% test coverage while reducing production bugs by 40–80%.
Master the red green refactor cycle of test driven development by writing a unit test, building production code with Resharper to pass, and refactoring, repeating until the feature is complete.
Master the three laws of test driven development by writing a failing test first. Keep tests minimal and avoid excessive production code, enabling rapid cycles and near 100% code coverage.
Parse roman numerals with the td style, using a dictionary to map symbols and subtractive notation. Refactor by extracting a well named is subtractive method and keeping tests passing.
Learn how continuous testing automates running related tests on code changes, leveraging tools like NCrunch and its live unit testing to speed feedback and support TDD.
Practice test-driven development by building a 3x3 tic tac toe game in c#, using a board, a moves counter, and a state enum for cross and zero, with tests.
Conclude by summarizing TDD principles, red green refactor, and three laws, with roman numerals conversion and tic tac toe as examples, showing continuous testing and client-driven API design.
Join the mailing list for discounts on paid courses and access links to other video courses, while leaving reviews and supporting the creator on Patreon.
Learn how to design and implement types in C# so that the other developers won't hate you when using one of the types developed by you. It means you are going to learn how to write code of the high quality: readable, understandable and reliable.
Improve your knowledge in object-oriented programming in the context of clean coding and building types of high quality.
Foundations of building object-oriented infrastructures
Despite the fact that C# is a very rich on features language, it's very common to see poorly designed and implemented types in a real world. In fact, C# is one of the richest on features language among object-oriented languages in the world nowadays. But with great power comes great responsibility. It's challenging to use all those features in a right way.
You probably have already heard the following well-known statement: most code sucks. Well, this course is all about how to produce code which doesn't suck.
Owning skills of producing a well-designed and well-implemented types is the prerequisite for the other developers to treat you as a real professional.
Content and Overview
This course is aimed at all the C# developers, from beginners to seniors. Topics which are covered in the course are relevant for all kinds of C# developers since all developers design and implement APIs. The topics complexity is very different. There are plenty of very simple topics, and at the same time, there are topics which require from you a solid C# background. There are plenty of code examples throughout this course, so you will learn both theoretical and practical material.
The course covers the following topics:
The list is far from being complete. The course covers a great number of topics. Enroll and start Mastering the Art of Writing Clean Code in C#!
------------------------------------------------------------
Keywords related to the course: