<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Eamon Keane</title>
    <description>The latest articles on DEV Community by Eamon Keane (@galwaycoder).</description>
    <link>https://dev.to/galwaycoder</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F270561%2F34719a6c-3131-45c3-8a15-028d4c134544.jpg</url>
      <title>DEV Community: Eamon Keane</title>
      <link>https://dev.to/galwaycoder</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/galwaycoder"/>
    <language>en</language>
    <item>
      <title>Why Naming Conventions are Important (and useful) in Software Development.</title>
      <dc:creator>Eamon Keane</dc:creator>
      <pubDate>Thu, 28 Jan 2021 19:44:47 +0000</pubDate>
      <link>https://dev.to/galwaycoder/why-naming-conventions-are-important-and-useful-in-software-development-d5j</link>
      <guid>https://dev.to/galwaycoder/why-naming-conventions-are-important-and-useful-in-software-development-d5j</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZD-0wKg6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1461958508236-9a742665a0d5%3Fcrop%3Dentropy%26cs%3Dtinysrgb%26fit%3Dmax%26fm%3Djpg%26ixid%3DMXwxMTc3M3wwfDF8c2VhcmNofDJ8fHdvcmRzfGVufDB8fHw%26ixlib%3Drb-1.2.1%26q%3D80%26w%3D2000" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZD-0wKg6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1461958508236-9a742665a0d5%3Fcrop%3Dentropy%26cs%3Dtinysrgb%26fit%3Dmax%26fm%3Djpg%26ixid%3DMXwxMTc3M3wwfDF8c2VhcmNofDJ8fHdvcmRzfGVufDB8fHw%26ixlib%3Drb-1.2.1%26q%3D80%26w%3D2000" alt="Why Naming Conventions are Important (and useful) in Software Development."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We've all heard of programming conventions. Every language seems to have it's own take on how you &lt;em&gt;should&lt;/em&gt; name something; should you use camelCase or PascalCase for the class name? How about a method? In C# you'd use PascalCase for method names whereas in Python uses lowercase_seperated_by_underscores also known as snake_case.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UTn6IaJf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2021/01/method-naming-convention-for-c--programming-language-example.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UTn6IaJf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2021/01/method-naming-convention-for-c--programming-language-example.png" alt="Why Naming Conventions are Important (and useful) in Software Development."&gt;&lt;/a&gt;C# naming convention for methods using PascalCase.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h-qSf58M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2021/01/method-naming-convention-for-python-programming-language-example.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h-qSf58M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2021/01/method-naming-convention-for-python-programming-language-example.png" alt="Why Naming Conventions are Important (and useful) in Software Development."&gt;&lt;/a&gt;Python naming convention for methods using snake_case.&lt;/p&gt;

&lt;p&gt;Naming conventions and indeed all style related conventions in programming are important.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bUt WhY?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It improves readability.&lt;/li&gt;
&lt;li&gt;It speeds up development.&lt;/li&gt;
&lt;li&gt;Onboarding new team members is faster.
&amp;lt;!--kg-card-end: markdown--&amp;gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Readability&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
When scanning through a file it makes it easy to pick out the various members by just looking at &lt;em&gt;how&lt;/em&gt; they're named. This shouldn't be underestimated as we read code way more than we write code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Velocity&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Naming a variable, method, field? Having naming conventions mean you don't even have to think about these things. You know what it should look like, you just have to come up with a good name. Good naming is another article in itself!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Onboarding new team members&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
You're joining a team that uses a new language? Cool, go and see how they name their members and then just follow suit. Obviously, if they're doing something crazy with their naming then you might want to discuss it without blindly following along.&lt;/p&gt;

</description>
      <category>softwaredesign</category>
      <category>development</category>
      <category>cleancode</category>
      <category>conventions</category>
    </item>
    <item>
      <title>Software Abstraction vs. Encapsulation</title>
      <dc:creator>Eamon Keane</dc:creator>
      <pubDate>Tue, 27 Oct 2020 21:34:29 +0000</pubDate>
      <link>https://dev.to/galwaycoder/software-abstraction-vs-encapsulation-dj3</link>
      <guid>https://dev.to/galwaycoder/software-abstraction-vs-encapsulation-dj3</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CA980Ko8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1518780664697-55e3ad937233%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CA980Ko8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1518780664697-55e3ad937233%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" alt="Software Abstraction vs. Encapsulation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm currently making my way through the highly commended book &lt;a href="https://www.amazon.com/gp/product/0735619670/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0735619670&amp;amp;linkCode=as2&amp;amp;tag=eamonkeane-20&amp;amp;linkId=d29c25cf9cb592f4da4634c1769b138e"&gt;Code Complete&lt;/a&gt; by Steve McConnell.   &lt;/p&gt;

&lt;p&gt;This book consistently ranks in the top 5 books for software developers. I've only just started to read it but it's plaudits are well deserved. There's so much value packed into it.&lt;/p&gt;

&lt;p&gt;I'm going to distill what I believe the essential differences between Abstraction and Encapsulation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Abstraction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sLXWGDrt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1524169358666-79f22534bc6e%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sLXWGDrt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1524169358666-79f22534bc6e%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" alt="Software Abstraction vs. Encapsulation"&gt;&lt;/a&gt;Photo by &lt;a href="https://unsplash.com/@badashphotos?utm_source=ghost&amp;amp;utm_medium=referral&amp;amp;utm_campaign=api-credit"&gt;Ash Edmonds&lt;/a&gt; / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;amp;utm_medium=referral&amp;amp;utm_campaign=api-credit"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Steve describes abstraction as the ability to engage with a concept while safely ignoring &lt;em&gt;some&lt;/em&gt; of its details. He goes on to say that anytime we work with an aggregate of some sort we're working with an abstraction. We don't say that we're going to go visit someone's combination of glass, wood, concrete and nails, we say that we're going to visit someone's &lt;em&gt;house.&lt;/em&gt; We've just performed an &lt;em&gt;abstraction&lt;/em&gt;. We ignore the little things and lump them into the concept of a house.&lt;/p&gt;

&lt;p&gt;Good classes allow us to concentrate on working with their interfaces (the pieces we "see")  and ignoring how they work under the hood. We might have a class named &lt;em&gt;SchoolManager&lt;/em&gt; and it has a method named &lt;em&gt;EnrollStudent&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;When we work with an instance of the &lt;em&gt;SchoolManager&lt;/em&gt; class and we want to enroll a student, we can concentrate on working with the &lt;em&gt;EnrollStudent&lt;/em&gt; method and trust that it does what its supposed to. We can ignore irrelevant details at this level.   &lt;/p&gt;

&lt;p&gt;Under the hood, &lt;em&gt;EnrollStudent&lt;/em&gt; might add a student to a collection but when working with the &lt;em&gt;StudentManager&lt;/em&gt; object, we don't care about that.&lt;/p&gt;

&lt;p&gt;Most real world objects are abstractions. Think of the objects around you, they're all abstractions.&lt;/p&gt;

&lt;p&gt;Steve finishes off by saying that Abstraction allows you to take a simpler view of a complex concept.&lt;/p&gt;

&lt;h2&gt;
  
  
  Encapsulation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PxQKFMR1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1536160885591-301854e2ed04%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PxQKFMR1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1536160885591-301854e2ed04%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" alt="Software Abstraction vs. Encapsulation"&gt;&lt;/a&gt;Photo by &lt;a href="https://unsplash.com/@allthestars?utm_source=ghost&amp;amp;utm_medium=referral&amp;amp;utm_campaign=api-credit"&gt;Sophie Dale&lt;/a&gt; / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;amp;utm_medium=referral&amp;amp;utm_campaign=api-credit"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Where abstraction says '&lt;em&gt;You can look at an object at a high level of detail.'&lt;/em&gt; Encapsulation goes on to say that '&lt;em&gt;you aren't allowed to look at an object at ANY OTHER level of detail. '&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The author uses the analogy of a house and a door. Encapsulation is a way of saying that you can look at the outside of a house and you can see that there's a door. However, you can't get close enough to make out how the door is made or what material it's made off. Encapsulation prevents you from seeing the detail of the door. This is by design and for your own good!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Encapsulation helps to manage complexity by forbidding you to look at the complexity.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If this book sounds like it might be useful to here's an affiliate link you can use:&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.amazon.com/gp/product/0735619670/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0735619670&amp;amp;linkCode=as2&amp;amp;tag=eamonkeane-20&amp;amp;linkId=d29c25cf9cb592f4da4634c1769b138e"&gt;Code Complete by Steve McConnell&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
This helps with the cost of running my blog.&lt;/p&gt;

</description>
      <category>softwaredesign</category>
      <category>architecture</category>
    </item>
    <item>
      <title>The SOLID Principles in Software Design Explained</title>
      <dc:creator>Eamon Keane</dc:creator>
      <pubDate>Sun, 21 Jun 2020 18:18:45 +0000</pubDate>
      <link>https://dev.to/galwaycoder/the-solid-principles-in-software-design-explained-53n</link>
      <guid>https://dev.to/galwaycoder/the-solid-principles-in-software-design-explained-53n</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lPkJ7LS6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1563996588557-b969e2f2f757%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lPkJ7LS6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1563996588557-b969e2f2f757%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I planned on getting this finished earlier in the week but ended up shearing some of &lt;a href="https://eamonkeane.dev/about/"&gt;our sheep&lt;/a&gt; 🐑. A few days late, whatever, let's get cracking.   &lt;/p&gt;

&lt;p&gt;In this post you're going to learn about each of the &lt;strong&gt;5 SOLID Principles&lt;/strong&gt;. I've included some code examples to make them a bit more real. I've also added some thought exercises / mental models that helped me understand these principles in the hope that they'll help you too.  &lt;/p&gt;

&lt;p&gt;These principles are a subset of the principles promoted by  &lt;a href="https://en.wikipedia.org/wiki/Robert_C._Martin"&gt;Robert C. Martin&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;S - The Single Responsiblity Principle&lt;/li&gt;
&lt;li&gt;O - The Open/Closed Principle (OCP)&lt;/li&gt;
&lt;li&gt;L - The Liskov Substitution Principle (LSP)&lt;/li&gt;
&lt;li&gt;I - The Interface Segregation Principle (ISP)&lt;/li&gt;
&lt;li&gt;D - The Dependency Inversion Principle (DIP)
&amp;lt;!--kg-card-end: markdown--&amp;gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. The Single Responsibility Principle (SRP)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SxNvYa-b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1533574745199-4df19ce5c70b%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SxNvYa-b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1533574745199-4df19ce5c70b%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;Photo by &lt;a href="https://unsplash.com/@markusspiske?utm_source=ghost&amp;amp;utm_medium=referral&amp;amp;utm_campaign=api-credit"&gt;Markus Spiske&lt;/a&gt; / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;amp;utm_medium=referral&amp;amp;utm_campaign=api-credit"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The single responsibility is defined as follows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Each class should should have RESPONSIBILITY over a single part of the functionality provided by the program.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What does this mean practically though? As a beginner programmer this isn't very helpful. Let's expand on the concept.&lt;/p&gt;

&lt;p&gt;Examples of single responsibilities :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validating inputs.&lt;/li&gt;
&lt;li&gt;Performing business logic.&lt;/li&gt;
&lt;li&gt;Saving and retrieving information to / from a database.&lt;/li&gt;
&lt;li&gt;Formatting a document.&lt;/li&gt;
&lt;li&gt;Performing calculations for the document.
&amp;lt;!--kg-card-end: markdown--&amp;gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So if you see a class that is validating inputs, logging events, reading and writing information to the database and performing business logic, you have a class with A LOT of responsibilities; violating the Single Responsibility Principle.  &lt;/p&gt;

&lt;p&gt;How can you spot a class that may be violating the Single Responsibility Principle?&lt;/p&gt;

&lt;p&gt;The class may have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tight coupling&lt;/li&gt;
&lt;li&gt;Low cohesion&lt;/li&gt;
&lt;li&gt;No seperation of concerns
&amp;lt;!--kg-card-end: markdown--&amp;gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tight coupling&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Changing one class results in having to change a lot of other classes to get the program working again. Sound familiar? 😁&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Low Cohesion&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The class contains fields and methods/functions that are unrelated to each other in any meaningful way.  &lt;/p&gt;

&lt;p&gt;A good way to spot this is if methods in a class don't reuse the same fields. Each method is using different fields from the class.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No Separation Of Concerns&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Should my class that deals with validating an input be performing business logic and saving the data to the database? Not likely. Separate the program out into sections that deal with each concern.&lt;/p&gt;

&lt;p&gt;A classic real world example of something having too many responsibilities are the multi function knives. They try to do too much and end up doing nothing well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3ymEiHQa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/Worlds_largest_Swiss_Army_knife_wenger_giant_knife.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3ymEiHQa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/Worlds_largest_Swiss_Army_knife_wenger_giant_knife.jpg" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;World's largest multi-tool. Cool to look at but probably doesn't do any one of it's functions really well. It has too many responsibilities.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The Open/Closed Principle (OCP)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RZUc-ict--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1482859602406-7659b00979fb%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RZUc-ict--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1482859602406-7659b00979fb%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;Photo by &lt;a href="https://unsplash.com/@khachiksimonian?utm_source=ghost&amp;amp;utm_medium=referral&amp;amp;utm_campaign=api-credit"&gt;Khachik Simonian&lt;/a&gt; / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;amp;utm_medium=referral&amp;amp;utm_campaign=api-credit"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Software entities (classes, methods, modules) should be open for extension but closed for modification&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;What does this mean in a practical sense?&lt;/strong&gt;   &lt;/p&gt;

&lt;p&gt;You should be able to change the behaviour of a method without changing it's source code.  &lt;/p&gt;

&lt;p&gt;For simple methods, adding / changing the logic in the method is perfectly reasonable. If you have to revisit this method 3+ times (not a hard number) due to requirements changing, you should start to think about the Open/Closed Principle.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Closing code to modification, why would you want to do this?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Code that we don't alter is less likely to create bugs due to unforeseen side effects.  &lt;/p&gt;

&lt;p&gt;Here's an example of some code that is not closed for modification. We'll use a switch statement that will perform something different for each transport type.&lt;br&gt;&lt;br&gt;
If a new transport type needs to be handled by our program then we need to modify the switch statement; violating the Open/Closed Principle.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hrEG7TmB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/Open-Closed-Principle-Violation-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hrEG7TmB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/Open-Closed-Principle-Violation-1.png" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;A method that is violating the Open/Closed Principle&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So how can we achieve the Open Closed Principle in our code?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Typically we'd use&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parameters&lt;/li&gt;
&lt;li&gt;Inheritance&lt;/li&gt;
&lt;li&gt;Composition / Injection
&amp;lt;!--kg-card-end: markdown--&amp;gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Using Parameters:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The &lt;em&gt;AddNumbersClosed&lt;/em&gt; method is not &lt;strong&gt;Closed&lt;/strong&gt; for modification. If we have to alter the numbers that it's adding we have to change the method.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jl34Y7-X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/Closed-method-OCP.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jl34Y7-X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/Closed-method-OCP.png" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;A method that is not closed for modification. Violating the Open/Closed Principle.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;AddNumbersOpen&lt;/em&gt; method is &lt;strong&gt;Open&lt;/strong&gt; and extensible for situations where any two numbers need to be added. We don't need to &lt;em&gt;modify&lt;/em&gt; the method as long as we're adding two numbers. We can say that this method is closed for modification but open for extension.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7bSJOItN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/Open-method-OCP.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7bSJOItN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/Open-method-OCP.png" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;A method that is closed for modification. It adheres to the Open/Closed Principle&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using Inheritance:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;MakeSound()&lt;/em&gt; Method here is open for many different animals to make many different sounds.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VHqEJ1hu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/ocp-using-inheritance.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VHqEJ1hu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/ocp-using-inheritance.png" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;Abiding to the Open Closed Principle using object inheritance. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using Composition / Injection:&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;In the following example, the responsibility for making the sound has been moved to the &lt;em&gt;SoundMaker&lt;/em&gt; Class.&lt;br&gt;&lt;br&gt;
To add new behaviour, we could add a new class. This new class could provide some new behaviour to the _Dog c_lass.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1P0AAwiH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/ocp-using-composition-and-injection.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1P0AAwiH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/ocp-using-composition-and-injection.png" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;The &lt;em&gt;Dog&lt;/em&gt; class showing how new behaviour can be added by using composition.&lt;/p&gt;

&lt;p&gt;Why would you create a new class for new behaviour?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We know that stuff we've already built isn't affected.&lt;/li&gt;
&lt;li&gt;We can design the class to perfectly suit the new requirement.&lt;/li&gt;
&lt;li&gt;New behaviour can be added without interfering with old code.
&amp;lt;!--kg-card-end: markdown--&amp;gt;
* * *&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. The Liskov Substitution Principle (LSP)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Oguf3VxW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1559715541-5daf8a0296d0%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Oguf3VxW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1559715541-5daf8a0296d0%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;Photo by &lt;a href="https://unsplash.com/@brett_jordan?utm_source=ghost&amp;amp;utm_medium=referral&amp;amp;utm_campaign=api-credit"&gt;Brett Jordan&lt;/a&gt; / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;amp;utm_medium=referral&amp;amp;utm_campaign=api-credit"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Liskov Substitution Principle states that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Subtypes must be substitutable for their base types.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Ok great, but what does that mean practically?&lt;/strong&gt;   &lt;/p&gt;

&lt;p&gt;You may have learned about the 'is-a' relationship related to OOP inheritance.&lt;br&gt;&lt;br&gt;
e.g. A dog 'is-a' animal (I know it should be &lt;em&gt;an&lt;/em&gt; animal, cut me some slack for demo purposes ).  &lt;/p&gt;

&lt;p&gt;The Liskov Substitution Principle is basically stating that this 'is-a' relationship is not good enough for maintaining clean code. We should examine the relationship further and explore if we can slot in 'is-substitutable-for' instead.  &lt;/p&gt;

&lt;p&gt;e.g. A dog 'is-substitutable-for' an animal. Can we say that we can substitute our dog for the animal?   &lt;/p&gt;

&lt;p&gt;I'll show a classic example showing how the 'is-a' relationship can break down and cause some problems.  &lt;/p&gt;

&lt;p&gt;It has a fantastic name; the rectangle-square problem.&lt;/p&gt;

&lt;p&gt;Rectangle; 4 sides and 4 right angles.&lt;br&gt;&lt;br&gt;
Square; 4 equal sides and 4 right angles.  &lt;/p&gt;

&lt;p&gt;So.... A square 'is-a' rectangle.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B-BD5qPH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/LSP-diagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B-BD5qPH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/LSP-diagram.png" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;A square and a triangle. Wow&lt;/p&gt;

&lt;p&gt;We have a &lt;em&gt;Rectangle&lt;/em&gt; class that could look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wwgj3vO3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/lsp---rectangle-class.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wwgj3vO3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/lsp---rectangle-class.png" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;The R&lt;em&gt;ectangle &lt;/em&gt;class showing it's two properties; height and width.&lt;/p&gt;

&lt;p&gt;And we have a square class that inherits from the rectangle class, because a square 'is-a' rectangle. This is what the square class looks like.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1N08zKXP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/lsp---square-class.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1N08zKXP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/lsp---square-class.png" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;The &lt;em&gt;Square&lt;/em&gt; class that inherits from the &lt;em&gt;Rectangle&lt;/em&gt; class as it obeys the 'is-a' relationship.&lt;/p&gt;

&lt;p&gt;Now say we have a method that calculates the area of a rectangle. Should be pretty straightforward. We'll pass our rectangle as a parameter and return the width multiplied by the height.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yTWd-u8l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/lsp-area-calculator.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yTWd-u8l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/lsp-area-calculator.png" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;The &lt;em&gt;AreaCalculator&lt;/em&gt; class&lt;/p&gt;

&lt;p&gt;This  won't work when we have code like this:&lt;br&gt;&lt;br&gt;
We create a new Rectangle.&lt;br&gt;&lt;br&gt;
It has a &lt;em&gt;Height&lt;/em&gt; of 3 and a &lt;em&gt;Width&lt;/em&gt; of 2.&lt;/p&gt;

&lt;p&gt;Our expected result is an area of 6, however, the actual result is 4.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bUf8PYa7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/lsp-main-program.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bUf8PYa7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/lsp-main-program.png" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;Showing how the 'is-a' relationship check can let you down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why did this happen?&lt;/strong&gt;   &lt;/p&gt;

&lt;p&gt;If you look at the code for the square class. When the width property is set, it overwrites the height. So we actually created a square with a width of 2 AND height of 2.   &lt;/p&gt;

&lt;p&gt;This example is trivial and you can see that we instantiated a square. In real world programs this may not be as easy to spot. You might be receiving the object as a parameter from another class and not know it's type. This could lead to unintended results as shown above.&lt;/p&gt;

&lt;p&gt;It comes down to our Square not being 'substitutable-for' a rectangle. A square's sides must be of equal length but a rectangles width and height can be different. We didn't perform the check before inheriting from the Rectangle class.&lt;/p&gt;

&lt;p&gt;Some clues as to when your code is violating the LSP:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type checking&lt;/li&gt;
&lt;li&gt;Null checks&lt;/li&gt;
&lt;li&gt;NotImplementedExceptions
&amp;lt;!--kg-card-end: markdown--&amp;gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also perform the duck test:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If it looks like a duck and quacks like a duck but it needs batteries, you probably have the wrong abstraction - Derick Bailey&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  4. The Interface Segregation Principle (ISP)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Gx29pV4X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1573599451635-65ca56a9cdb3%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Gx29pV4X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1573599451635-65ca56a9cdb3%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;Photo by &lt;a href="https://unsplash.com/@willianjusten?utm_source=ghost&amp;amp;utm_medium=referral&amp;amp;utm_campaign=api-credit"&gt;Willian Justen de Vasconcellos&lt;/a&gt; / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;amp;utm_medium=referral&amp;amp;utm_campaign=api-credit"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What is the interface segregation principle?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Clients should not be forced to depend upon interfaces that they do not use - &lt;a href="https://en.wikipedia.org/wiki/Robert_C._Martin"&gt;Bob Martin&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The client in this case is any &lt;strong&gt;calling code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Take a look at this interface name &lt;em&gt;IPersonService&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
It has three methods. Any client that implements this interface will have to implement these methods.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ODt7ZBeG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/interface.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ODt7ZBeG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/interface.png" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;The IPersonService Interface&lt;/p&gt;

&lt;p&gt;Now let's take this Child class that implements the &lt;em&gt;IPersonService&lt;/em&gt; Interface.   &lt;/p&gt;

&lt;p&gt;For a child, the &lt;em&gt;SetSalary()&lt;/em&gt; method and the &lt;em&gt;Salary&lt;/em&gt; property do not make sense!  &lt;/p&gt;

&lt;p&gt;The client (child class) depends on an interface that it does not use. ❌  &lt;/p&gt;

&lt;p&gt;The interface is only partially implemented 😒.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--scDdu5XC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/ISP---Child-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--scDdu5XC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/ISP---Child-1.png" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;The Child class implementing the IPersonService. It's depending on code that it doesn't use, namely the members related to Salary&lt;/p&gt;

&lt;p&gt;See that method throwing the &lt;em&gt;NotImplementedException()&lt;/em&gt; ? It's a good sign that you're violating the Interface Segregation Principle.&lt;/p&gt;

&lt;p&gt;This isn't so bad here, but it will become a problem with larger interfaces. It introduces higher coupling ( I like to think of high coupling as classes being super-glued together and tougher to separate). Future changes to the code will be more difficult.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do we remedy this?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Split the interface into more &lt;em&gt;cohesive&lt;/em&gt; interfaces.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Av_e9PlP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/interface-segregation-principle-cohesive-interfaces.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Av_e9PlP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/interface-segregation-principle-cohesive-interfaces.png" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;Two new cohesive interfaces created by splitting up the IPersonService. &lt;/p&gt;

&lt;p&gt;The &lt;em&gt;IPersonSalaryService&lt;/em&gt; is an interface that defines members related to a person's salary.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;IPersonNameService&lt;/em&gt; does the same for members related to a person's name. Both are more cohesive than the original &lt;em&gt;IPersonService&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Now our client code (&lt;em&gt;Child&lt;/em&gt; class) can depend on code that it actually uses. Much better. 😎&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3Jmh2fRZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/interface-segregation-principle-child-class.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3Jmh2fRZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/interface-segregation-principle-child-class.png" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;Child class depending on a more cohesive IPersonNameService&lt;/p&gt;

&lt;p&gt;We can easily implement multiple classes in C# using this syntax. Take a look at this Adult class. It depends on code (the two interfaces) that it actually uses. ✅&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E13L7E0h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/interface-segregation-principle-adult-class.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E13L7E0h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/interface-segregation-principle-adult-class.png" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;The Adult class implementing both the IPersonNameService and the IPersonSalaryService.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. The Dependency Inversion Principle (DIP)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2wpz6X-M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1531871165793-30177cc75a44%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2wpz6X-M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1531871165793-30177cc75a44%3Fixlib%3Drb-1.2.1%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D2000%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;Photo by &lt;a href="https://unsplash.com/@nadineshaabana?utm_source=ghost&amp;amp;utm_medium=referral&amp;amp;utm_campaign=api-credit"&gt;Nadine Shaabana&lt;/a&gt; / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;amp;utm_medium=referral&amp;amp;utm_campaign=api-credit"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Dependency Inversion Principle states that&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"High-level modules should not depend on low level modules. Both should depend on abstractions.&lt;br&gt;&lt;br&gt;
Abstractions should not depend on details. Details should depend on abstractions"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&amp;lt;!--kg-card-begin: markdown--&amp;gt;&amp;lt;!--kg-card-end: markdown--&amp;gt;&lt;/p&gt;

&lt;p&gt;In a C# project, your project references will point in the direction your dependencies.   &lt;/p&gt;

&lt;p&gt;In domain driven design or onion architecture as it's sometimes called, the references will point away from low-level (implementation code) and towards your business logic / domain layer.   &lt;/p&gt;

&lt;p&gt;You can think of high-level code as being more process-orientated. It's more abstract and more concerned with the business rules.   &lt;/p&gt;

&lt;p&gt;Low level code is the plumbing code.&lt;/p&gt;

&lt;p&gt;Here's an example showing what high-level code and low-level code might look like in a program.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B6Wq9HLs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/Dependency-Inversion-Principle-diagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B6Wq9HLs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/06/Dependency-Inversion-Principle-diagram.png" alt="The SOLID Principles in Software Design Explained"&gt;&lt;/a&gt;Diagram showing what high-level and low-level code might look like. &lt;/p&gt;

&lt;p&gt;The Domain layer is just concerned with publishing a course. As we move to lower level code we get more concrete. See changes to the course status id - this is low level code (In the context of a language like C#).  &lt;/p&gt;

&lt;p&gt;Abstractions are generally achieved using interfaces and abstract base classes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/ardalis"&gt;@ardalis&lt;/a&gt; put it really well when he said that they're generally types that can't be instantiated (Read, you can't make a new object from them).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Abstractions define a contract, they don't do the work&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;Abstractions specify &lt;strong&gt;WHAT&lt;/strong&gt; should be done without telling us &lt;strong&gt;HOW&lt;/strong&gt; they should be done.&lt;/p&gt;

&lt;p&gt;Again, thinking of abstractions in terms of a contract is a useful exercise.&lt;/p&gt;

&lt;p&gt;I like to think of an abstraction speaking to any class that depends on the abstraction as saying something like:&lt;/p&gt;

&lt;p&gt;_ &lt;strong&gt;"This is what you must do, I don't care how you do it."&lt;/strong&gt; -_ Abstraction speaking to a class that depends on it.   &lt;/p&gt;

&lt;p&gt;This may seem stupid. It helps me understand abstractions and interfaces and how they can be used to make programs easier to design and manage.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If it's stupid, but works, it ain't stupid!&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;So that's it, by now you'll have a better understanding of these 5 principles and you can start incorporating them into your work. You'll be aware of them if nothing else and being aware of them is half the battle.&lt;/p&gt;

&lt;p&gt;I first learned about these principles in my University but what really drove them home was the SOLID Principles for C# developers course by &lt;a href="https://ardalis.com/"&gt;Steve Smith&lt;/a&gt; on Pluralsight called 'SOLID Principles for C# Developers'. I highly recommend it.&lt;/p&gt;

&lt;p&gt;If you have any questions pop them into the comment section below or reach out to me on &lt;a href="https://twitter.com/eamokeane"&gt;twitter where I post coding tips regularly&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>softwaredesign</category>
      <category>csharp</category>
      <category>architecture</category>
    </item>
    <item>
      <title>How to Inspect the SQL Generated by Entity Framework Core using .NET Core's built in Logging</title>
      <dc:creator>Eamon Keane</dc:creator>
      <pubDate>Sat, 16 May 2020 12:36:42 +0000</pubDate>
      <link>https://dev.to/galwaycoder/how-to-inspect-the-sql-generated-by-entity-framework-core-using-net-core-s-built-in-logging-18do</link>
      <guid>https://dev.to/galwaycoder/how-to-inspect-the-sql-generated-by-entity-framework-core-using-net-core-s-built-in-logging-18do</guid>
      <description>&lt;p&gt;Today I'm going to show you how to intercept and view the SQL generated by Entity Framework Core. This method takes advantage of Microsoft's built in logging for .NET core.&lt;/p&gt;

&lt;p&gt;This is something I wish i knew about starting off. I hope it's of use to somebody else.&lt;/p&gt;

&lt;p&gt;This method is an alternative to profiling the SQL using something like SQL Server Management Studio. This will work with an ASP.NET Core application which should cover the vast majority of use cases!&lt;/p&gt;

&lt;p&gt;By default, .NET core outputs logs to the following locations when you call HostCreateDefaultBuilder(args) within Program.cs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Console&lt;/li&gt;
&lt;li&gt;Debug&lt;/li&gt;
&lt;li&gt;Event Source&lt;/li&gt;
&lt;li&gt;EventLog (Windows Only)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-3.1"&gt;Default providers for logging is ASP.Net Core 3.1 (Microsoft Documentation)&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.  Enable Sensitive Data Logging
&lt;/h3&gt;

&lt;p&gt;Navigate to your startup file for your .NET Core project (Startup.cs). Now find where you've configured your application to use Entity Framework Core. This should be in the ConfigureServices method.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--15Xx8q51--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/psilmjdxqlh0w8rtbf3e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--15Xx8q51--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/psilmjdxqlh0w8rtbf3e.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enable sensitive data logging by calling the EnableSensitiveDataLogging method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DutchContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
                &lt;span class="n"&gt;cfg&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseSqlServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetConnectionString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DutchConnectionString"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;EnableSensitiveDataLogging&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--szWPq3Y6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dfmvrihe2aluv3o4m64u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--szWPq3Y6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dfmvrihe2aluv3o4m64u.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enabling Sensitive Data Logging allows you to view the parameters being passed into the SQL Queries in the logs.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.   Configure the Logging using your Configuration File
&lt;/h3&gt;

&lt;p&gt;The next step is to tell your ASP.NET Core App to log Entity Framework Core commands.&lt;/p&gt;

&lt;p&gt;For this step, go to your config file. Typically this is named 'Appsettings.json'. It's likely you configured the connection string for your application here.&lt;/p&gt;

&lt;p&gt;This is what mine looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IE-mCu3f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/non5l2c6hepolh70ci44.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IE-mCu3f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/non5l2c6hepolh70ci44.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add a new line  to "Logging" =&amp;gt; "LogLevel"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt; &lt;span class="s"&gt;"Microsoft.EntityFrameworkCore.Database.Command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Information"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The logging config should now look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="s"&gt;"Logging"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"LogLevel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;"Default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Information"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Microsoft"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Warning"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Microsoft.EntityFrameworkCore.Database.Command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Information"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My final configuration file:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ULc3hx8E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bzcrvi6612piegeqqx6n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ULc3hx8E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bzcrvi6612piegeqqx6n.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it!&lt;/p&gt;

&lt;p&gt;You can now run your application and see the SQL generated by Entity Framework Core in any of the default providers mentioned earlier.&lt;/p&gt;

&lt;p&gt;Here I'm using the output window in Visual Studio 2019 and showing the output from ASP.NET Core Web Server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nY7gr73j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/if4rngipzjc3d9p7sdjd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nY7gr73j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/if4rngipzjc3d9p7sdjd.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you can't see the output window just use 'Ctrl + Alt + O' to bring it up or find it in the View menu at the top of visual studio.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article first appeared on Eamon Keane's Blog at &lt;a href="https://eamonkeane.dev/how-to-view-sql-generated-by-entity-framework-core-using-logging/"&gt;www.eamonkeane.dev&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Hope this helps someone out! &lt;/p&gt;

&lt;p&gt;Let me know if it helps you out in the comments below &lt;/p&gt;

&lt;p&gt;I'm also over on twitter where I tweet about software development. Call over and say hello! &lt;a href="https://twitter.com/eamokeane/"&gt;@eamokeane&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>sql</category>
      <category>dotnet</category>
      <category>entityframeworkcore</category>
    </item>
    <item>
      <title>How to Create Computed Columns in Entity Framework Core</title>
      <dc:creator>Eamon Keane</dc:creator>
      <pubDate>Sun, 03 May 2020 10:18:36 +0000</pubDate>
      <link>https://dev.to/galwaycoder/how-to-create-computed-columns-in-entity-framework-core-2kem</link>
      <guid>https://dev.to/galwaycoder/how-to-create-computed-columns-in-entity-framework-core-2kem</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HEpVX7dD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/05/EF-Core-computed-columns-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HEpVX7dD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/05/EF-Core-computed-columns-2.png" alt="How to Create Computed Columns in Entity Framework Core"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I recently ran into an challenge when using Entity Framework Core. I wanted to search across a property which consisted of an &lt;strong&gt;integer&lt;/strong&gt; and a &lt;strong&gt;prefix&lt;/strong&gt;. The example at the end of this post goes through the solution.&lt;/p&gt;

&lt;p&gt;I'll start off with a common scenario.&lt;/p&gt;

&lt;p&gt;Say for example you want to search for a user across their &lt;em&gt;Full name&lt;/em&gt;. However,your table only contains their &lt;em&gt;Firstname&lt;/em&gt; and &lt;em&gt;Lastname&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Kc0PfooN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/05/1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Kc0PfooN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/05/1.png" alt="How to Create Computed Columns in Entity Framework Core"&gt;&lt;/a&gt;Typical table design for a user. It stores their Firstname and Lastname.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class StoreUser : IdentityUser
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }

    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your search input may look something like this, it takes a string value and finds users based on that input string.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qOj8ZP-Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/05/image-5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qOj8ZP-Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/05/image-5.png" alt="How to Create Computed Columns in Entity Framework Core"&gt;&lt;/a&gt;Search input to find Users&lt;/p&gt;

&lt;p&gt;The current table design restricts the ability to search across the users' Full name. I could resort to writing something like this in the repository:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        {
            return context.Users.Where(u =&amp;gt; u.FirstName.ToLower().Contains(searchTerm) 
            || u.LastName.ToLower().Contains(searchTerm));
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using this approach, searching using the term '&lt;em&gt;Eamon K&lt;/em&gt;' in the search input would yield no results.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hqMX3Xv4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/05/image-6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hqMX3Xv4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/05/image-6.png" alt="How to Create Computed Columns in Entity Framework Core"&gt;&lt;/a&gt;User in the database. We only store the FirstName and LastName. (Viewed using SQL Server Management Studio).&lt;/p&gt;

&lt;p&gt;Entity Framework would generate TSQL that would search the table and check if &lt;strong&gt;FirstName&lt;/strong&gt; had the term '&lt;em&gt;Eamon K&lt;/em&gt;'. False.&lt;br&gt;&lt;br&gt;
It would then do the same for &lt;strong&gt;LastName&lt;/strong&gt; , also return false. Thus it would return no results.&lt;/p&gt;

&lt;p&gt;This isn't the behaviour we've come to expect from a search by term input shown above. Here's how I went about fixing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Entity Framework computed columns.
&lt;/h2&gt;

&lt;p&gt;We could simply introduce a new property to the StoreUser class called &lt;em&gt;Fullname&lt;/em&gt;. Then introduce some code on user creation or update that checks the FirstName and LastName and updates the Fullname property.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class StoreUser : IdentityUser
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
        public string FullName { get; set; }

    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's a better way though. We'd rather not have to deal with maintaining this Fullname property.&lt;/p&gt;

&lt;p&gt;First we'll set the FullName property to have a private setter to avoid unintentionally assigning it.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class StoreUser : IdentityUser
   {
       public string FirstName { get; set; }
       public string LastName { get; set; }
       public string FullName { get; private set; }

   }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we'll use the fluent API to define how we want this column to be calculated in the database. We're doing this withing the Within the &lt;strong&gt;OnModelCreating&lt;/strong&gt; method.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;protected override void OnModelCreating(ModelBuilder modelBuilder)
       {
           base.OnModelCreating(modelBuilder);

           modelBuilder.Entity&amp;lt;StoreUser&amp;gt;()
               .Property(u =&amp;gt; u.FullName)
               .HasComputedColumnSql("[FirstName] + ' ' + [LastName]");
       }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that has been added, add new migration. Mine looked like this:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public partial class computedcolumnadded : Migration
  {
      protected override void Up(MigrationBuilder migrationBuilder)
      {
          migrationBuilder.AddColumn&amp;lt;string&amp;gt;(
              name: "FullName",
              table: "AspNetUsers",
              nullable: true,
              computedColumnSql: "[FirstName] + ' ' + [LastName]");
      }

      protected override void Down(MigrationBuilder migrationBuilder)
      {
          migrationBuilder.DropColumn(
              name: "FullName",
              table: "AspNetUsers");
      }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update the database and you should now see the new column added to the table!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hPAwb4_o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/05/image-9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hPAwb4_o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/05/image-9.png" alt="How to Create Computed Columns in Entity Framework Core"&gt;&lt;/a&gt;SQL server understands that this column is computed. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AnrEX8Ii--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/05/image-10.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AnrEX8Ii--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/05/image-10.png" alt="How to Create Computed Columns in Entity Framework Core"&gt;&lt;/a&gt;Computed column specification added. (Viewed using SQL Server Management Studio).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UGuWdwYV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/05/image-7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UGuWdwYV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/05/image-7.png" alt="How to Create Computed Columns in Entity Framework Core"&gt;&lt;/a&gt;SQL computed column added&lt;/p&gt;

&lt;p&gt;Now back to why we made this change in the first place ....  &lt;/p&gt;

&lt;p&gt;We can rewrite our repository method like so&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  public IQueryable&amp;lt;StoreUser&amp;gt; GetUsersByTerm(string searchTerm)
        {
            return context.Users.Where(u =&amp;gt; u.FullName.ToLower().Contains(searchTerm));
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Making this change allows us to search using the term '&lt;em&gt;Eamon K&lt;/em&gt;' and return the correct user. You could add an index to this column if needed.&lt;/p&gt;

&lt;p&gt;Computed columns are very powerful. Entity Framework Core with its fluent API allows them to be easily added.  &lt;/p&gt;

&lt;p&gt;You'll often see scenarios where a property is made up for a underlying incrementing number along with a &lt;em&gt;prefix&lt;/em&gt; or &lt;em&gt;suffix&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This is a perfect place to take advantage of computed columns.&lt;/p&gt;

&lt;p&gt;Here's another quick example:&lt;/p&gt;

&lt;p&gt;You're a company that conducts tests. The test has a primary key of type int and also has a property named '&lt;em&gt;TestReference&lt;/em&gt;'.&lt;/p&gt;

&lt;p&gt;Test reference is made up of the primary key along with a prefix&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KaRTehmZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/05/image-8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KaRTehmZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eamonkeane.dev/content/images/2020/05/image-8.png" alt="How to Create Computed Columns in Entity Framework Core"&gt;&lt;/a&gt;Example of how the TestReference column might look in the table.&lt;/p&gt;

&lt;p&gt;You could use Entity Framework Fluent API to configure this as&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;modelBuilder.Entity&amp;lt;Test&amp;gt;()
           .Property(t =&amp;gt; t.TestReference)
           .HasComputedColumnSql("N'Test'+ RIGHT('00000'+CAST(Id AS VARCHAR(5)),5)");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows you to now query the database for this TestReference column without having to worry about maintaining it.&lt;/p&gt;

&lt;p&gt;More information on computed columns can be found in the Microsoft documentation here&lt;/p&gt;

&lt;p&gt;[&lt;/p&gt;

&lt;p&gt;Generated Values - EF Core&lt;/p&gt;

&lt;p&gt;How to configure value generation for properties when using Entity Framework Core&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yiSjiuUR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://docs.microsoft.com/favicon.ico" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yiSjiuUR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://docs.microsoft.com/favicon.ico" alt="How to Create Computed Columns in Entity Framework Core"&gt;&lt;/a&gt;AndriySvyrydMicrosoft Docs&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WJuRh92v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://docs.microsoft.com/en-us/media/logos/logo-ms-social.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WJuRh92v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://docs.microsoft.com/en-us/media/logos/logo-ms-social.png" alt="How to Create Computed Columns in Entity Framework Core"&gt;&lt;/a&gt;&lt;br&gt;
](&lt;a href="https://docs.microsoft.com/en-us/ef/core/modeling/generated-properties"&gt;https://docs.microsoft.com/en-us/ef/core/modeling/generated-properties&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;I hope this post helped somebody out. Let me know if you have any questions. You can find me on twitter &lt;a href="https://twitter.com/eamokeane"&gt;@ &lt;strong&gt;eamokeane&lt;/strong&gt;&lt;/a&gt;. Say hello!&lt;/p&gt;

</description>
      <category>entityframworkcore</category>
      <category>csharp</category>
      <category>sqlserver</category>
    </item>
  </channel>
</rss>
