Dependency Injection in .NET Core 2.0 - Marino Posadas - E-Book

Dependency Injection in .NET Core 2.0 E-Book

Marino Posadas

0,0
45,59 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.

Mehr erfahren.
Beschreibung

Inject dependencies and write highly maintainable and flexible code using the new .NET Core DI Engine

About This Book

  • Identify when to use the constructors, parameters, setters, or Interface Injection, for best results
  • Build dependencies not only for MVC within .NET but also for other frontend tools such as Angular
  • Create specific components or services to cover discrete and separate pieces of functionality and call them when needed.

Who This Book Is For

C# and .NET developers who have no idea what DI is and would like to understand how to implement it in their applications.

What You Will Learn

  • Understand the concept of DI and its implications in modern software construction
  • Learn how DI is already implemented in today's frameworks.
  • Analyze how DI can be used with current software to improve maintainability and scalability.
  • Learn the use of DI in .NET Core
  • Get used to the possibilities that DI offers the ASP.NET Core developer in different scenarios.
  • Learn about good practices and refactoring legacy code.

In Detail

.NET Core provides more control than ever over web application architectures. A key point of this software architecture is that it's based on the use of Dependency Injection as a way to properly implement the Dependency Inversion principle proposed in the SOLID principles established by Robert C. Martin.

With the advent of .NET Core, things have become much simpler with Dependency Injection built into the system. This book aims to give you a profound insight into writing loosely-coupled code using the latest features available in .NET Core. It talks about constructors, parameter, setters, and interface injection, explaining in detail, with the help of examples, which type of injection to use in which situation. It will show you how to implement a class that creates other classes with associated dependencies, also called IoC containers, and then create dependencies for each MVC component of ASP.NET Core. You'll learn to distinguish between IoC containers, the use of Inversion of Control, and DI itself, since DI is just a way of implementing IoC via these containers. You'll also learn how to build dependencies for other frontend tool such as Angular. You will get to use the in-built services offered by .NET Core to create your own custom dependencies.

Towards the end, we'll talk about some patterns and anti-patterns for Dependency Injection along with some techniques to refactor legacy applications and inject dependencies.

Style and Approach

Filled with examples, this book will take you through various techniques for injecting dependencies into your applications with or without the use of frameworks.

Sie lesen das E-Book in den Legimi-Apps auf:

Android
iOS
von Legimi
zertifizierten E-Readern

Seitenzahl: 443

Veröffentlichungsjahr: 2017

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Dependency Injection in .NET Core 2.0

 

 

 

 

 

 

 

 

Make use of constructors, parameters, setters, and interface injection to write reusable and loosely-coupled code

 

 

 

 

 

 

 

 

Marino Posadas
Tadit Dash

 

 

 

 

 

 

 

BIRMINGHAM - MUMBAI

Dependency Injection in .NET Core 2.0

 

Copyright © 2017 Packt Publishing

 

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the authors, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

 

First published: November 2017

 

Production reference: 1071117

 

Published by Packt Publishing Ltd.
Livery Place
35 Livery Street
Birmingham
B3 2PB, UK.

 

ISBN 978-1-78712-130-0

www.packtpub.com

Credits

Authors

Marino Posadas

Tadit Dash

Copy Editor

Safis Editing

Reviewer

Gaurav Aroraa

Project Coordinator

Prajakta Naik

Commissioning Editor

Aaron Lazar

Proofreader

Safis Editing

Acquisition Editor

Denim Pinto

Indexer

Pratik Shirodkar

Content Development Editor

Lawrence Veigas

Graphics

Jason Monteiro

Technical Editor

Tiksha Sarang

Production Coordinator

Aparna Bhagat

 

About the Authors

Marino Posadas is an independent senior trainer, writer, and consultant in Microsoft Technologies and Web Standards. He is a Microsoft MVP in C#, Visual Studio, and Development Technologies; an MCT, MCPD, MCTS, MCAD, and MCSD; and he was the former Director of Development in Spain and Portugal for Solid Quality Mentors.

Marino has published 15 books and more than 500 articles on development technologies in several magazines and online publications. The topics covered in his books range from Clipper and Visual Basic 5.0/ 6.0 to C # and .NET- safe programming, programming with Silverlight 2.0 and 4.0, and Web Standards.

His latest books are Mastering C# and .NET Framework, by Packt, and The Guide to Programming in HTML5, CSS3, and JavaScript with Visual Studio. He is also a speaker at Microsoft events, having lectured in Spain, Portugal, England, the US, Costa Rica, and Mexico.

His website also contains developer's resources and videos, in English and Spanish, interviewing representatives of the Microsoft and Web Standards development world.

You can follow him on Twitter at @MarinoPosadas.

I'd like to thank Dominic Pereira, Denim Pinto, Lawrence Veigas, and Tiksha Sarang from Packt for their continuous support and confidence while writing this book. Special thanks to some professionals and technology evangelists whose work inspired different parts of this book, in particular, Mark Russinowich, Scott Hanselman, Scott Hunter (the "lesser" Scotts), and, of course, Robert Martin and Martin Fowler, pioneers in this work. Also, I would like to remember my MVP lead, Cristina González Herrero, for her continuous encouragement and help, and other people at Microsoft who have always supported my activities. My memories go here to Alfonso Rodríguez, David Carmona, David Salgado, and Leon Welicki. My appreciation also goes to my mates at Netmind for their support in this initiative from the beginning. I dedicate this book to my wife, Milagros, who makes everything possible.

 

Tadit Dash is a software engineer by profession. As a software engineer, he usually works for 8 to 9 hours daily. Besides his daily work, he contributes to both online and offline communities. He co-founded the first technical community in his state, named Microsoft Developers Community Odisha, which is devoted to spreading awareness of the newest trends in technology among developers. This community organizes events and workshops in orphanages, schools, and colleges.

He writes articles and blogs and creates demos and videos for fellow programmers. Answering questions on online forums and social channels are the activities he enjoys the most. Due to his exceptional contribution to the technical community, Microsoft has awarded him with the Microsoft Most Valuable Professional accolade since 2014. CodeProject has awarded him the CodeProject MVP accolade (the first from Odisha and three times in a row for the years 2014, 2015, and 2016). For his constant mentorship, IndiaMentor featured him as a Young Mentor on their site.

He was recognized by DZone and awarded the Most Valuable Blogger accolade. He was awarded the Star and Achiever accolade from his organization. Motivating students in his sessions is something he is popular for. He is a regular technical and motivational speaker. He has spoken at many local events organized by different communities. He was a featured speaker in DevTechDay Nepal.

I would like to dedicate this book to my grandfather, the late Mr. Ganeswar Tripathy. My grandmother Santipriya Tripathy, father, Dr. Gobinda Chandra Dash, mother, Mrs. Sasmita Tripathy, and brother, Tworit Dash who made sure that I am high on energy (with healthy food) and confidence all the time during writing. My uncles, Mr. Anil Tripathy, Mr. Aswin Tripathy, and Mr. Amiya Tripathy who always guide me to shape the approach to my new challenges. Mrs. Sujata Tripathy, who takes cares of me like my mother and Mr. Debendra Rath, my uncle, who never misses an opportunity to discuss ideas to strengthen my thoughts so that I deliver the best. My guide and mentor, Mr. Gaurav Kumar Aroraa (who is a Microsoft MVP and renowned author), encouraged me to take up the project, and constantly motivated me throughout the preparation. I am so grateful to the Packt team, especially Mr. Lawrence Veigas(Content Development Editor), and Miss. Tiksha Sarang who corrected me in every chapter. Thanks to Mr. Nirmal Hota (mobile guru of Odisha), who is like my big brother, for his consistent efforts in throwing me out of my comfort zone while patting my back. Miss. Prakreeti Prasanna, as a well wisher and best friend, always adds an x-factor to my activities. All my friends, family members, colleagues, and Google, of course, are the ingredients for the success of this book. Special thanks to my community members, Microsoft Developers Community, Odisha, for waiting to hear the surprise. Last, but not the least, Miss. Jayashree Satapathy, who, being a part of my life, has taken every care to make my writing schedule smooth.

 

About the Reviewer

Gaurav Aroraa has his M.Phil in computer science. He is a Microsoft MVP, lifetime member of the Computer Society of India (CSI), Advisory member of IndiaMentor, certified scrum trainer/coach, XEN for ITIL-F and APMG for PRINCE-F and PRINCE-P. He is an Open Source developer, contributor to TechNet Wiki, and the founder of Innatus Curo Software LLC. For over 19 years of his career, he has mentored thousands of students and industry professionals. You can tweet Gaurav on his twitter handle at @g_arora.

He has authored the following books:

Building Microservices in ASP.NET Core, Packt Publishing

Learn C# in 7 Days, 

Packt Publishing

SOLID Principles Succinctly, Syncfusion

ASP.NET WebHooks Succinctly

, Syncfusion

 

To my wife, Shuby Arora, and my angel (daughter), Aarchi Arora, who permitted me to steal some time for this book from the time I was supposed to spend with them. To the entire Packt team, especially Prajakta, whose coordination and communication during the period was tremendous.

www.PacktPub.com

For support files and downloads related to your book, please visit www.PacktPub.com.

Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.

At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks.

https://www.packtpub.com/mapt

Get the most in-demand software skills with Mapt. Mapt gives you full access to all Packt books and video courses, as well as industry-leading tools to help you plan your personal development and advance your career.

Why subscribe?

Fully searchable across every book published by Packt

Copy and paste, print, and bookmark content

On demand and accessible via a web browser

Customer Feedback

Thanks for purchasing this Packt book. At Packt, quality is at the heart of our editorial process. To help us improve, please leave us an honest review on this book's Amazon page at https://www.amazon.com/dp/1787121305.

If you'd like to join our team of regular reviewers, you can e-mail us at [email protected]. We award our regular reviewers with free eBooks and videos in exchange for their valuable feedback. Help us be relentless in improving our products!

Table of Contents

Preface

What this book covers

What you need for this book

Who this book is for

Conventions

Reader feedback

Customer support

Downloading the example code

Downloading the color images of this book

Errata

Piracy

Questions

The SOLID Principles of Software Design

In the beginning

.NET and .NET Core

About .NET Core

ASP.NET Core

About the IDE used in this book

Other foundational changes in .NET Core

The SOLID principles

The Single Responsibility Principle (SRP)

The background of the Separation of Concerns (SoC)

Well-known examples of Separation of Concerns

A basic sample of Separation of Concerns

Another sample

The Open/Closed principle

Back to our sample

The Liskov Substitution principle

Back to the code again

Other implementations of LSP in .NET

The Interface Segregation principle

Another sample

The Dependency Inversion principle

The (more or less) canonical example

Other ways to implement Dependency Inversion

Summary

Dependency Injection and IoC Containers

The Dependency Principle in more detail

Let's look at an example

Aspects of Dependency Injection

Object Composition

Object Lifetime

Interception

Ways to implement DI

Property Injection in action

Method Injection in practice

.NET event architecture as Model Injection

DI containers

Service locators

DI Containers for .NET

Using Unity Container

Using Castle Windsor

Using StructureMap

Using Autofac

Dependency Injection in other frameworks

DI in Angular

Our first demo

Summary

Introducing Dependency Injection in .NET Core 2.0

The main characteristics of .NET Core

The main advantages of .NET Core

Installation of .NET Core in the IDE

Installation path for .NET Core in Visual Studio 2015

.NET Core in Visual Studio 2017

Types of deployment

Checking other dependencies in .NET Core

Dependency Injection in .NET Core

DI Architecture and Object's Lifetime

The class ActivatorUtilities and other helpers

The Microsoft.Extensions.DependencyInjection container

Checking the object's lifetime

Mapping interfaces to instance classes

The concept of Scope Applied to services

Other extensions with DI functionality

A reflection on the structure of .NET Core

LogLevels Severity

Summary

Dependency Injection in ASP.NET Core

ASP.NET Core from the command-line tools

Creating the minimum possible application

Changing to ASP .NET Core

Middleware

The Startup class and Dependency Injection

Code explanation

The New ASP.NET servers

Kestrel

WebListener

Dependency Inversion in the architecture - OWIN

Analyzing the default template

Configuration files

The Entry Point

The default Startup class

Dependency Injection in ASP.NET Core

Services provided by ASP.NET Core

The relation of services available at startup

Identifying Services in the Web Application template

Using Dependency Injection in ASP.NET MVC Views

Garbage Collection and Custom Services

Using Custom Services through Dependency Injection

Services and data management

Using Dependency Injection inside Views

Summary

Object Composition

Understanding object relationships

Object Composition

Types of Object Composition

Composition

Consider an example

Contrasting features of Composition

Why are subclasses inside Composition?

Important notes

Aggregation

Consider an example

Composition versus Aggregation

Advantages and disadvantages

Other important relationships

Association

Example

Explanation of the preceding code

Types of Association

Reflexive Association

Indirect Association

Composition over Inheritance

Inheritance

Example on User class

New User Type

Problem which we come across

The solution to the problem

Role of Object Composition in Dependency Injection

Composition Root

Composing .NET Core 2.0 Console application

Object Composition in ASP.NET Core MVC 2.0

Summary

Object Lifetime

Manage the object life cycle

Stack versus heap

Managed and unmanaged resources

Generations

Object creation

The Copy constructor

Object destruction

Finalize

The IDisposable interface

Consider an example

Implementing the IDisposable Interface

Step1 -  Basic structure of class

Step2 - Defining a Dispose Overload method

Step3 -Modifying the Dispose(bool) for Derived classes

Step 4 - Handling duplicate Dispose calls

Object lifetime management in .NET Core

Object creation

Designing the interfaces

The Concrete class

The Service class

The controller

View

Startup ConfigureServices

Object lifetimes

Singleton

Scoped

Transient

Instance

Object disposal

When to choose what?

Relationship and dependencies among lifetimes

Singleton depending on Scoped and Transient

Scoped depending on Singleton and Transient

Transient depending on Singleton and Scoped

Summary

Interception

Introducing Interception

The decorator

Patterns and principles for Interception

Benefits of the Decorator approach

Problems of the Decorator approach

Aspect-oriented programming

Cross-cutting concerns

Aspect

Aspect characteristics

Advantages

Aspect attached locations

Types of AOP

Investigating Interception

The Interception process

Castle Windsor

Demonstration for using the Castle Windsor

Creating an Interceptor

Attaching an Interceptor

Intermediate Language (IL) Weaving

IL Weaving process

Creating an aspect

Attaching the aspect

Interception in ASP.NET Core

Filters

Global filter

Attributes

Middleware

Registration

Execution

Ordering

Summary

Patterns - Dependency Injection

Dependency Inversion Principle

Problems

Solution

Inversion of Control (IoC)

Patterns

Constructor Injection pattern

The problem

The solution

Curveball

Injecting with .NET Core 2.0

Implementation inside ASP.NET Core 2.0

ControllerActivatorProvider.cs

Importance of the Constructor Injection pattern

Advantages of the Constructor Injection pattern

Disadvantages of the Constructor Injection pattern

Property Injection pattern

Curveball

Advantages of the Property Injection Pattern

Disadvantages of the Property Injection Pattern

Method Injection Pattern

Curveball

Injecting with .NET Core 2.0

Implementation inside .NET Core 2.0

MvcServiceCollectionExtensions.cs

Ambient context

Curveball

Implementation inside .NET Core 2.0

The advantages of the Ambient Context

The disadvantages of the Ambient Context

Summary

Anti-Patterns and Misconceptions on Dependency Injection

When does Dependency Injection become an anti-pattern?

Anti-patterns

Control Freak

Problem

Concrete Factory

Abstract Factory

Static Factory

Solution

Poor Man's DI

The approach

Problem

Solution

Bastard Injection

Problem

Solution

Constrained Construction

Problem

Solution

Service Locator

Design

Advantages

Problem

Code reusability

Solution

Refactoring steps

Summary

Dependency Injection in Other JavaScript Frameworks

TypeScript

Architectural changes

Modules in TypeScript

External modules

Dependency Injection in TypeScript

Angular

AngularJS

Examples using Visual Studio 2017

Understanding the structure of AngularJS bootstrap

Data access and Dependency Injection

Summing up Dependency Injection features inside AngularJS

Angular 2+

Microsoft's TypeScript is the preferred language in Angular 2+ 

Angular tools

Working with Angular

Editing the initial project

The structure of the main module

DI in Angular 4

The concept of a provider

Wrapping it up

Summary

Best Practices and Other Related Techniques

Tightly coupled systems

The problem

The solution - refactoring with DI

Interface extraction

Layered architecture

The problem - The concrete class reference again

Misuse of business and Data Access Layer assemblies

Best practice for layered architecture

Managed Extensibility Framework (MEF)

Layers and MEF implementation

Introduction of IUser

The IModuleRegistrar interface

The ModuleRegistrar class

The IModule interface

The ModuleInit class

The ModuleLoader class

Executing the ModuleLoader.LoaderContainer() method from Web App

What have we achieved with MEF?

Layers are separated

All classes inside layers are now internal

No concrete class instantiation inside the UI Layer

More layers can be added to the architecture

Conclusion

Summary

Preface

This book is an approach to the implementation of Dependency Injection techniques across the new .NET Core 2.0 version. The designers of .NET Core implemented plenty of functionalities related to good practices and have followed the principles stated by Robert C. Martin (the SOLID principles) in distinct areas of this version.

The purpose of this work is to go through those well-stated principles and identify and show through examples how they're implemented, and how they can be used by the programmer.

What this book covers

Chapter 1, The SOLID Principles of Software Design, introduces you to the five SOLID principles and how they are found or can be easily implemented in .NET Core 2.0.

Chapter 2, Dependency Injection and IoC Containers, gives you exposure to how Dependency Injection should be used either by itself or with the help of third-party containers.

Chapter 3, Introducing Dependency Injection in .NET Core 2.0, reviews the real implementation of DI inside .NET Core 2.0 from the point of view of Console applications.

Chapter 4, Dependency Injection in ASP.NET Core, provides a more detailed study of the implementation of DI techniques inside web applications that use ASP.NET Core 2.0, full of samples.

Chapter 5, Object Composition, takes you through all the hidden principles behind the concept of object composition and how it is applied in .NET Core 2.0 and ASP.NET Core MVC 2.0, forming a pillar of DI.

Chapter 6, Object Lifetime, the next DI pillar provides a deep dive into lifestyles maintained and typical management strategies, by the objects with DI in place, which enables better decision making with optimized configurations.

Chapter 7, Interception, the last pillar of DI ecosystem, provides techniques to intercept calls and insert code dynamically into the pipeline. This chapter also deals with interception's application in .NET Core 2.0 and ASP.NET Core 2.0 with proper illustrations.

Chapter 8, Patterns – Dependency Injection, walks you through the D of SOLID and all the important techniques to apply DI in applications with .NET Core 2.0.

Chapter 9, Anti-Patterns and Misconceptions on Dependency Injection, deals with the common bad usage of DI patterns and scenarios to avoid while coding, in order to get a good outcome from DI in the application.

Chapter 10, Dependency Injection in Other JavaScript Frameworks, teaches you about Dependency Injection techniques using other popular frameworks, such as Angular.

Chapter 11, Best Practices and Other Related Techniques, covers the well-proven coding, architectural, and refactoring practices that you should adopt while applying DI in your current and legacy applications.

What you need for this book

You will need Visual Studio 2017 Community Edition, the Chrome Navigator, and IIS (Internet Information Server Express) to successfully test and execute all code files.

Who this book is for

This book is for C# and .NET developers who have no idea what DI (Dependency Injection) is and would like to understand how to implement it in their applications.

Reader feedback

Feedback from our readers is always welcome. Let us know what you think about this book-what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of. To send us general feedback, simply e-mail [email protected], and mention the book's title in the subject of your message. If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors.

Customer support

Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.

Downloading the example code

You can download the example code files for this book from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you. You can download the code files by following these steps:

Log in or register to our website using your e-mail address and password.

Hover the mouse pointer on the

SUPPORT

tab at the top.

Click on

Code Downloads & Errata

.

Enter the name of the book in the

Search

box.

Select the book for which you're looking to download the code files.

Choose from the drop-down menu where you purchased this book from.

Click on

Code Download

.

Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:

WinRAR / 7-Zip for Windows

Zipeg / iZip / UnRarX for Mac

7-Zip / PeaZip for Linux

The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Dependency-Injection-in-.NET-Core-2.0. We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!

Downloading the color images of this book

We also provide you with a PDF file that has color images of the screenshots/diagrams used in this book. The color images will help you better understand the changes in the output. You can download this file from https://www.packtpub.com/sites/default/files/downloads/DependencyInjectioninNETCore20_ColorImages.pdf.

Errata

Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books-maybe a mistake in the text or the code-we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title. To view the previously submitted errata, go to https://www.packtpub.com/books/content/support and enter the name of the book in the search field. The required information will appear under the Errata section.

Piracy

Piracy of copyrighted material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy. Please contact us at [email protected] with a link to the suspected pirated material. We appreciate your help in protecting our authors and our ability to bring you valuable content.

Questions

If you have a problem with any aspect of this book, you can contact us at [email protected], and we will do our best to address the problem.

The SOLID Principles of Software Design

This book focuses on techniques related to Dependency Injection and the way those techniques are implemented by default and can be extended by the programmer in .NET Core--the first version of .NET that executes on every platform.

It works on Windows, macOS, and Linux distro on the desktop, and the idea can even be extended to the mobile world covering the Apple, Android, and Tizen (Samsung) operating systems.

This is, with no doubt, the most ambitious project from Microsoft in its search for a universal coverage of programming technologies and tools, and it can be considered a natural step after the initial UWP (Universal Windows Platform) project that allows building applications for any device supporting Windows, from IoT devices to the desktop, XBOX, or HoloLens.

So, in this chapter we'll start with a quick review of the main architectural components of .NET Core and its derivative frameworks (such as ASP.NET Core), to be followed with the foundations on which Dependency Injection techniques are based, as part of the SOLID principles, stated by Robert C. Martin (Uncle Bob) in 2000. (See Wikipedia: https://en.wikipedia.org/wiki/SOLID_(object-oriented_design).)

Therefore, we'll revise those five SOLID principles, explaining their purpose and advantages, together with some basic implementations of each one of them in the C# language using Console applications coded in .NET Core. In all we'll see an explanation of each principle and its coverage:

Separation of concerns (clearly implemented in the core infrastructure of .NET Core and also from the initial configuration of pipelines and middleware in ASP.NET Core)

Open/Closed (already implemented in classic .NET Framework since version 3.0 and also present here)

Liskov Substitution Principle (available in two ways--in a classic manner through the support of typecasting, and through the use of generics)

Interface segregation: Explanation of Interface segregation and its advantages

Dependency Inversion: Explanation of the principle, its derivatives, and the concept of IoC containers

In the beginning

The evolution of programming techniques is, somehow, related to language evolution. Once the initial (and, in some ways, chaotic) times had passed, the universality of computing became clear, and the need for good patterns and languages capable of affording large projects turned out to be evident.

The 70s marked the start of the adoption of other paradigms, such as procedural programming, and later on, object-oriented programming (OOP), proposed by Ole-Johan Dahl and Kristen Nygaard with the Simula language, when they both worked at the Norwegian Computing Center. They were given the Turing Award for these achievements, among other recognitions.

A few years later (around 1979), Bjarne Stroustrup created C with Classes, the prototype of what C++ is today because he found valuable aspects in the Simula language, but he thought that it was too slow for practical purposes, being the first OOP language that was universally adopted.

C++ originally had imperative features and object-oriented and generic ones, while also providing the ability to program for low-level memory manipulation. While it's true that it has become a de facto standard for building critical systems and applications, for many people it was not adequate for LOB (Line of Business) applications.

Years later, Java and the .NET platforms proposed a much easier and affordable solution for many programmers while still moving within the ordered space that object-oriented programming languages promote.

So, OOP was adopted, and so far no other important programming paradigm has replaced these ideas. Certainly, there are other approaches, such as functional programming, but even the most significant representative of this tendency, JavaScript, is becoming more object-oriented in the latest versions (ECMAScript 2015).

.NET and .NET Core

.NET has been revamped lately in order to achieve the goal that Microsoft has pursued since Satya Nadella arrived in the company--"Any Developer, Any App, Any Platforms.".

According to Principal Manager Scott Hunter, the company now presents a set of unified application models that can be summarized in the following screenshot:

Source: http://www.hanselman.com/blog/AnUpdateOnASPNETCore10RC2.aspx

As you see, the situation now is quite promising for a .NET Developer. The screenshot shows a Common Infrastructure (compilers, languages, and runtime components), powered by Roselyn services and other features. All those integrate with the IDEs that support these projects, now including Visual Studio for Mac.

On top of that lies a .NET Standard Library, which has points in common that allow us to share code along the three different frameworks--the classic .NET Framework (in version 4.6.2, at the time of writing this), .NET Core (now in version 2.0), and Xamarin, which allows building applications for any type of mobile target--Android, iOS, Windows Phone, and Tizen (Samsung).

About .NET Core

.NET Core is the new version of .NET presented officially in the summer of 2016, and updated to version 1.1 in the November Connect() event the same year. It's defined as a cross-platform, open source, cloud-ready and modular .NET platform for creating modern web apps, microservices, libraries, and console applications that run everywhere (Windows, Linux, and MacOS).

It can be deployed along with the application itself, minimizing installation issues.

Prior to its publication, Microsoft decided to restart the numbering, reinforcing the idea that this is a totally new concept with respect to classical versions, as a better way to avoid ambiguities.

MSDN architect Cesar de la Torre defines in his blog very precisely the goals and structure of .NET Core--unlike the traditional .NET Framework, which is a single package installation, system-wide, and Windows-only runtime environment, .NET Core is about decoupling .NET from Windows, allowing it to run in non-Windows environments without having to install a giant 400 Mb set of binaries (versus just the footprint of the components you need from .NET Core) plus the ability to deploy applications accompanying the framework itself, supporting side-by-side execution of different versions of the framework.

A very interesting part of its architecture and deployment infrastructure, as mentioned in the same source, is that instead of being part of the operating system, .NET Core is composed of NuGet packages and is either compiled directly into an application or put into a folder inside the application. This means applications can carry .NET Core within and thus are completely side by side on the machine.

I, personally, think this is absolutely crucial for the project to be successful. No side-effects, no component installation in the target machine, and no dependencies. (As you'll see throughout this book this avoiding of dependencies is totally foundational when building software that follows good practices.)

NET Core 2.0 - Supported OS Versions Proposal:

OS

Version

Architectures

Notes

Windows Client

7 SP1+

x64, x86

Windows Server

2008 R2 SP1+

x64, x86

Configurations: Full, Server Core, Nano

Windows IoT

10+

[C] arm32

IoT Core - see

Raspberry Pi instructions

Red Hat Enterprise Linux

7.3+

x64

This includes Centos and Oracle Linux

Fedora

25+

x64

Debian

8.7+

x64

Debian 9 (Stretch) workaround

Ubuntu

14.04+

x64, [C] arm32

This includes Linux Mint 17 for x64 For arm32, see

Raspberry Pi instructions

openSUSE

42.2+

x64

Tizen

4+

[S] arm32

Tizen .NET Developer Preview

Mac OS X

10.12+

x64

In Progress OS's

Arch Linux

[C] TBD

TBD

Blocked on

missing OpenSSL 1.0 package

in distro. Arch Linux community efforts tracked

here

.

FreeBSD & NetBSD

[C] TBD

TBD

Tracking

main issue

and

label

. NetBSD packages for

.NET Core 1.0.0

As for the types of programmable project available from any of the above-mentioned IDE's, .NET Core can support its own application model, and also the Universal Windows Platform Model, optionally compiled to .NET Native (see the following screenshot):

Source: http://www.hanselman.com/blog/AnUpdateOnASPNETCore10RC2.aspx

We end this introduction to .NET Core with the summary from the same page mentioned previously in relation to this framework:

Cross-platform

: .NET Core currently supports three main operating systems--Linux, Windows and OS X. There are other OS ports in progress such as FreeBSD, NetBSD, and Arch Linux. .NET Core libraries can run unmodified across supported OSes. The apps must be re-compiled per environment, given that apps use a native host. Users select the .NET Core supported environment that works best for their situation.

Open Source

: .NET Core is available on GitHub at

https://github.com/dotnet/core/blob/master/release-notes/2.0/2.0.0-preview1.md

, licensed with the MIT and Apache 2 licenses (licensing is per component). It also makes use of a significant set of open source industry dependencies (see release notes). Being OSS is critical for having a thriving community plus a must for many organizations where OSS is part of their development strategy.

Natural acquisition

: .NET Core is distributed as a set of NuGet packages that developers can pick and choose from. The runtime and base framework can be acquired from NuGet and OS-specific package managers, such as APT, Homebrew, and Yum. Docker images are available on docker hub. The higher-level framework libraries and the larger .NET library ecosystem are available on NuGet.

Modular framework

: .NET Core is built with a modular design, enabling applications to include only the .NET Core libraries and dependencies that are needed. Each application makes its own .NET Core versioning choices, avoiding conflicts with shared components. This approach aligns with the trend of developing software using container technologies such as Docker.

Smaller deployment footprint

: Even when in v1.0/1.1 the size of .NET Core is a lot smaller than .NET Framework; note that the overall size of .NET Core doesn't set out to be smaller than the .NET Framework over time, but since it is pay-for-play, most applications that utilize only parts of CoreFX will have a smaller deployment footprint.

Fast release cycles of .NET Core

: .NET Core's modular architecture plus its OSS nature provide more modern and much faster release cycles (even per NuGet package) compared to slow release cycles from larger monolithic frameworks. This approach allows a much faster innovation pace from Microsoft and the OSS .NET community than what was traditionally possible with the .NET Framework.

Thus, there are multiple application model stacks built on top of the .NET Core that allow developers to build applications ranging from console applications, across UWP Windows 10 apps (PC, tablet, and phones) to scalable web applications and microservices with ASP.NET Core.

ASP.NET Core

ASP.NET applications that use .NET Core promote a model based on the previous MVC model, although built from scratch, targeted at cross-platform execution, the elimination of some unnecessary features, and the unification of the previous MVC with the web API variant; so, they work with the same controller type.

Besides this, the code doesn't need to be compiled prior to execution while you're developing. The BrowserSync technology allows you change the code on-the-fly and the Roselyn services take care of updating; so, you just have to refresh your page to see the changes.

ASP.NET Core also uses a new hosting model, completely decoupled from the web server environment that hosts the application. It supports IIS versions and also self-hosting contexts via Kestrel (cross-platform, extremely optimized, built on top of LibUv, the same component that Node.js uses) and WebListener HTTP (Windows-only) servers.

As part of its architecture, it proposes a new generation of middleware that is asynchronous, very modular, lightweight, and totally configurable, where we define things such as routing, authentication, static files, diagnostics, error handling, session, CORS, localization; and they can even be user-defined.

Notice also that ASP.NET Core can run as well in the classic .NET Framework with access to the functionality exposed by those libraries. The following screenshot shows the schema:

ASP.NET Core joins many things that were separate in previous versions. Thus, there are no distinctions between MVC and Web API and, if you target .NET Core or if you prefer to target any of the other version of .NET, the architectural model can be MVC using this rebuilt architecture.

In addition, a new built-in IoC container for dependency injection is responsible for bootstrapping the system, together with a new configuration protocol, which we'll see in practice in the following chapters.

About the IDE used in this book

Since this book deals with .NET Core and ASP.NET Core and their built-in capabilities covering SOLID principles in general and DI in particular, we're using the latest available version of Visual Studio (Visual Studio 2017 Enterprise), which includes full support for these platforms, together with a bunch of convenient extensions and templates.

You can also use Visual Studio 2017 Community Edition, which is free, or any higher version with practically no changes, as far as the codes samples are concerned.

If you're a Mac user, you can also use Visual Studio for Mac (https://www.visualstudio.com/vs/visual-studio-mac/), available since November 2016, and, if you prefer a light, full-fledged, and free IDE for any platform (Linux, Mac or Windows), you can opt for Visual Studio Code (https://code.visualstudio.com/download), which also has excellent editing and debugging capabilities. All of them have full support for .NET Core/ASP.NET Core as well (see the following screenshot):

Throughout this and other chapters, I'll use indiscriminately .NET Core or ASP.NET Core for the demos, depending on whether we need a more complex user interface or not. Notice also that .NET Core (for the time being) does not offer any visual UI beyond Console applications.

Actually, the currently available templates shown by default when we select New Project and click on .NET Core are the ones you can see in the following screenshot:

As you see, the choices are basically threefold (besides testing): Console apps, Class libraries, and ASP.NET Core Web apps, based on NET Core. In the three cases, the resulting apps run on any platform.

Other foundational changes in .NET Core

It's important to keep in mind that, with NET Core, you no longer depend on .NET Framework libraries (the BCL libraries), either installed by the OS or manually and located in the GAC (Global Assembly Cache).

All libraries are available via NuGet and downloaded accordingly. But, if you have tried .NET Core prior to Visual Studio 2017, you might miss the file project.json in which all dependencies were referenced.

The official documentation states that when using Visual Studio 2017:

MSBuild supports .NET Core projects, using a simplified

csproj

project format that makes it easier to be edited by hand, without the need for unloading the project

There is support for file wildcards in the project file, enabling folder-based projects that don't require individual files to be included

NuGet package references are now part of the

csproj

format, consolidating all project references in one file

So, if you try a new .NET Core project with this tool, the project's dependencies are now referenced in the csproj file (in XML format), as you can see when opening it in any text editor:

In parallel, Visual Studio reads that file, creates a Dependencies entry in the Solution Explorer, and starts looking for that information (either in the PC's cache or in NuGet).

Note also that they're not real, classic DLLs, but fragments of code that are assembled all together at compile time to minimize size and launch time. If you take a look at that entry you can see the Dependencies' dependencies, and so on:

Another critical point to highlight relates to the deliverables produced after the compiling process. If you open the demo included as ConsoleApp1 (or create a basic one of your own), and just compile it, you'll see that the bin directory does not contain any executable file. You'll see a DLL with that name instead (ConsoleApp1.dll).

When you launch the application (after adding a Console.Read() sentence to stop execution), you'll see that the executable is, indeed, dotnet.exe. And the same is true when you open the Diagnostics Tool and take a snapshot of the executable to see what is in place in that moment. The following screenshot shows the situation:

The reason for this is directly related to the complexity of this model. The application is thought to execute on distinct platforms. The default option allows the deployment architecture to determine the best way to configure the JIT compilers depending on the target. This is why the execution is undertaken by the dotnet runtime (named dotnet.exe).

From the point of view of deployment, in .NET Core, two types of application are defined: portable and self-contained.

In .NET Core, portable applications are the default. Of course, that means that (as developers) we can be sure about their portability in distinct .NET core installations. However, a standalone app does not depend on any previous installation to run. That is to say, it holds within itself all the necessary components and dependencies, including the runtime packaged with the application. Certainly, that builds a larger app, but it also makes the application capable of executing on any .NET Core platform whether you have .NET Core installed in the target or not.

For the main purposes of this book, it doesn't matter which runtime mode we choose. Anyhow, this brief introduction can give you an idea of how the new framework behaves and is managed inside Visual Studio 2017.

And, remember, anything I do using Visual Studio 2017, you can also do with Visual Studio Code.

The SOLID principles

Some programming guidelines have a comprehensive, general-purpose intention, while others are mainly designed to fix certain specific problems. Therefore, before we focus on specific problems, it's important to review those features that can be applied in different scenarios and solutions. I mean those principles that you should consider beyond the type of solution or specific platform to program for.

This is where the SOLID principles (and other related problems) come into play. In 2001, Robert Martin published a foundational article on the subject (http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod), in which he enumerated a set of principles and guidelines that, in his own words, focus very tightly on dependency management, its potential problems, and how to avoid them.

To explain this further, in his words, poor dependency management leads to code that is hard to change, fragile, and non-reusable. So, this principle is directly related with two of the OOP mantras--reusability, and maintainability (the capacity to change as the project grows, one of the main goals of inheritance).

Overall, Martin stated his 11 commandments to consider, but they can be divided into three areas:

The five SOLID principles, which deal with class design

The other six principles, mainly focused on packages--three of them are about package cohesion, and the other three explain the dangers of package coupling and how to evaluate a package structure

We're going to start with the SOLID principles, which by extension not only affect the class design, but also other aspects of software architecture.

The application of these ideas has, for example, been decisive in important modifications made to the HTML5 standard. Concretely, the application of the SRP (Single Responsibility principle) only highlighted the need to totally separate presentation (CSS) from content (HTML) and the subsequent deprecation of some tags (<cite>, <small>, <font>).

This applies to other popular frameworks as well, such as AngularJS (and even more in Angular 2), both designed not only with the Single Responsibility principle in mind but also based on the Dependency Inversion principle (the D in SOLID).

The following diagram schematizes the five principles' initials and correspondences:

The explanation of every letter in the acronym as expressed in Wikipedia is as follows:

S - Single Responsibility Principle

: A class should have only a single responsibility (that is, only one potential change in the software's specification should be able to affect the specification of the class). Martin states that this principle is based on the principle of cohesion, previously defined by Tom de Marco in a book named

Structured Analysis and Systems Specification

and by Meilir Page-Jones in his work

The Practical Guide to Structured Systems Design

.

O - Open/Closed Principle

: Software entities should be open for extension, but closed for modification. Bertrand Meyer was the first to propose this principle. Martin puts this in another way at

http://www.butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod

, saying that

You should be able to extend a class's behavior, without modifying it.

L - Liskov Substitution principle

: Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program. Barbara Liskov first stated this, and Martin rephrases the principle in this manner--

Derived classes must be substitutable for their base classes

.

I - Interface Segregation principle

:

Many client-specific interfaces are better than one general-purpose interface

. Robert C. Martin was the first to use and formulate this principle, which he rewords in the aforementioned article as--

Make fine grained interfaces that are client specific.

D - Dependency inversion principle

:

We should 'Depend on Abstractions'. Do not depend upon concretions

. This too is an idea developed by Robert C. Martin.

The Single Responsibility Principle (SRP)

The Single Responsibility Principle (SRP), focuses on the fact that there should never be more than one reason for a class to change. In this context, responsibility is defined as a reason for a change. If, under any circumstances, more than one reason comes up to change the class, then the class' responsibilities are multiple and should be redefined.

This is, indeed, one of the most difficult principles to apply properly because as Martin says, conjoining responsibilities is something that we do naturally. In his book, Agile Principles, Patterns, and Practices in C#, Martin proposes a canonical example to show the differences, as follows:

interface Modem { public void dial(String phoneNumber); public void hangup(); public void send(char c); public char recv(); }

Given the previous interface, any class implementing it has two responsibilities: connection management and the communication itself. Such responsibilities can be used from the different parts of an application, which, in turn, might change as well.

We're going to use the Visual Studio 2017 Class Designer to express the way Martin proposes we express this class design instead:

As we see, in Martin's solution, the class depends on two interfaces, each one in charge of a responsibility--connection and channel transmission (two abstractions, really: remember that an interface is not compiled and it only serves as a contract for the compiler to check).

However, one wonders, should these two responsibilities be separated? It only depends on application changes. To be precise, the key here is to know whether changes in the application affect the signature of connection functions. If they do, we should separate both; otherwise, there's no need for separation because we would then create needless complexity.

So, overall, a reason to change is the key, but keep in mind that a reason to change is applicable only if changes occur.

In other situations, there might be reasons to keep distinct responsibilities together as long as they are closely related to the business definitions or have to do with the hardware requirements of the operating system.

The background of the Separation of Concerns (SoC)

As always happens, there were previous approaches to the problem of software separation. Dijkstra in "On the role of scientific thought" (http://www.cs.utexas.edu/users/EWD/transcriptions/EWD04xx/EWD447.html) mentioned that It is what I sometimes have called "the separation of concerns", which, even if not perfectly possible, is yet the only available technique for effective ordering of one's thoughts, that I know of.

Another advance was Information Hiding, defined by Wikipedia (https://en.wikipedia.org/wiki/Information_hiding) as the principle of segregation of the design decisions in a computer program thataremost likely to change, thus protecting other parts of the program from extensive modification if the design decision is changed. This was the seed that later became a basic pillar of OOP--Data Encapsulation.

Even Barbara Liskov, whom we mentioned in connection with the substitution principle, published at the same time Programming With Abstract Data Types (http://dl.acm.org/citation.cfm?id=807045), which she describes as an approach to the computer representation of abstraction. The definition of ADTs as a class of objects whose logical behavior is defined by a set of values and a set of operations links data and functionality.

Later approaches have improved these ideas. Proposals for Code Contracts, originally introduced by Bertrand Meyer in his Eiffel language, and implemented in C# via Code Contracts (https://msdn.microsoft.com/es-es/library/dd264808(v=vs.110).aspx) foster the use of pre and post conditions that our software has to accomplish.

Finally, we can think of the separation of what Hayim Makabee (https://effectivesoftwaredesign.com/2012/02/05/separation-of-concerns/) reports as cross-cutting concerns--aspects that might affect distinct pieces of software in even distinct layers of the application and that should be managed in a similar fashion (authorization or instrumentation issues, and so on.). In .Net, we count on Attributes, applicable equally to classes and class members, to modify and tune such behavior.

A bit later in the same article, Makabee clearly establishes the main purposes for these techniques. If we understand coupling as the degree of dependency between two modules, the goal is to obtain low coupling. Another term is cohesion or the measure of how strongly-related the set of functions performed by a module is. Obviously, high cohesion is better.

He ends by summarizing the benefits obtained with these techniques:

Patterns and methodologies are always intended to reduce coupling and at the same time increase congruity. By hiding information, we reduce coupling since we isolate implementation details. Thus, ADT's reduce coupling by using clear and abstract interfaces. We have an ADT specifying the set of function that can be executed on a type, that's more cohesive than a global data structure modified by external functions. The way that OOP reaches that cohesion is the implementation of two of its basic principles--encapsulation and polymorphism, together with dynamic binding. Furthermore, inheritance reinforces cohesion by means of hierarchies that are based on generalization and specialization, which permits a suitable separation from the functionality belonging to a superclass from its subclasses. AOP, in turn, supplies solutions for cross-cutting concerns in a way that both aspects and functionality may become more cohesive.

Maintainability, reusability, and extensibility are only three of the main advantages gained with its implementation.

Well-known examples of Separation of Concerns

All of us have gone through cases and scenarios where the separation of concerns lies at the heart of the system or technology that implements it. One such case is HTML (and, especially HTML5).

Since its inception, the standard HTML5 was thought to clearly separate content from presentation. And the popularity of mobile devices only made that requirement more evident. The huge variety of form factors available today demanded a technology capable of adapting to these sizes, in such a way that content could be held by HTML tags and the final presentation in a given device decided at runtime depending on the device.

Therefore, some tags were declared deprecated, such as <font>, <big>, <center>, and a list of others, and the same happened to some attributes, such as background, align, bgcolor, or border since they didn't make sense in this new system. Even some of them that still remain unchanged and that have a visual effect on the output (such as <b>, <i>, or <small>) are kept for their semantic meaning and not for their presentational effects, which is a role totally dependent on CSS3.