Reengineering .NET: Injecting Quality, Testability, and Architecture into Existing Systems

By Bradley Irby

Published by Addison-Wesley Professional

Published Date: Oct 23, 2012

More Product Info

Description

Many of the systems written over the years are still in place and working, but are in desperate need of updated technology and approaches in order to compete with software being developed today. Reengineering .NET addresses the problem of aging software.  In it, leading .NET architect Bradley Irby introduces best practices for revitalizing older Microsoft .NET code. Irby shows how to integrate new tools and development advances into existing systems that can't go offline. Using a step-by-step approach, .NET professionals can make their legacy software more reliable, maintainable, attractive, and usable -  for years to come. Through real-world case studies and extensive downloadable sample code, Irby shows how to: * Compare each leading architectural option for reengineering older .NET software, and choose the right alternatives * Introduce unit testing into applications that weren't built for it * Systematically modernize aging code bases while keeping applications fully available * Master specific design patterns for reengineering .NET code * Organize the reengineering project so appropriate expertise is applied to each task This book assumes moderate familiarity with .NET, but no specific expertise with reengineering, testing, or .NET architecture: all key concepts are explained simply, with practical examples drawn from the author's 20+ years of enterprise consulting experience.

Table of Contents

Preface     xiii
Acknowledgments     xix
About the Author     xxi
PART I Target Architecture
1  Implementing a Service-Oriented Architecture     3
An Overview of the Service-Oriented Architecture     4
Understanding Standardized Service Contracts     6
  Interfaces     6
Understanding Coupling     12
Understanding Service Abstraction     15
Designing Reusable Services     18
Understanding Service Autonomy and Service Composability     18
Understanding Service Statelessness     19
A Service Example     24
Summary     26
2  Understanding Application Architecture     27
Working with Architectural Patterns     27
An Overview of Architectural Patterns     28
Differences Among MVP, MVC, and MVVM     29
  Model Access     30
  View Models     31
Handling UI Events     38
How Do the Patterns Work?     43
Which Pattern Should You Choose?     45
Summary     45
3  Unit Testing     47
An Example of Unit Testing     48
Creating Unit Tests     49
Writing a Test     52
Detecting Exceptions     58
Understanding the Power of Assert     61
Comparing Unit Tests to Integration Tests     61
Using the InternalsVisibleTo Attribute     62
Understanding Test Driven Development     65
Learning More About Unit Testing     65
Summary     66
4  Understanding the Dependency Inversion Principle     67
Understanding Tight Coupling     67
Implementing the Abstract Factory Pattern     74
Introducing Interfaces     79
Creating Unit Tests     82
Understanding Service Location     84
  Inversion of Control Containers     84
  Service Locator     88
  A Real World Example     90
  OnDemand Service Properties     96
  Unit Testing Advantages     99
  Final Tweaks     100
Using Dependency Injection     103
Why Is Service Location Better for Reengineering?     108
Summary     113
5  Using Test Doubles with Unit Tests     115
How Do Test Doubles Work?     115
What Need Do Test Doubles Satisfy?     116
Creating a Stub     119
  Distinguishing Between Mocks and Stubs     123
Creating a Mock     124
  A Second Mocking Example     128
  A Third Mocking Example     129
Using Mocking System Services     130
Learning More About Test Doubles     133
Summary     133
PART II Reengineering
6  Initial Solution Review     137
Analyzing the Code     138
  Basic Architecture     138
  Code Structure     139
  Database Access     140
  Data Structures     140
  External Interfaces     141
  Application Controls Versus Form Controls     142
Analyzing the General Code Structure     142
Managing Language Migration     144
Removing Dead Code     145
Using Global Variables     145
Converting Code: It’s Not All or Nothing     149
Using an Automated Code Conversion Utility     150
Using Data Access Technologies     152
  Detecting the Data Model     152
  Detecting the Data Access Pattern     154
Summary     155
7  Planning the Project     157
Managing Expectations     157
Creating the Reengineering Team     158
Identifying Development Tools and the Build Process     159
  Introducing Source Control     160
  Introducing Defect Tracking     161
  Installing and Using a Continuous Integration (CI) Server     161
Cleaning Up Legacy Solutions     162
Establishing the Foundation      163
Refactoring to Use Basic Services     164
Refactoring to Use Advanced Services     166
Reporting Progress to Stakeholders     166
Managing Communication and Training     167
Summary     168
8  Identifying Development Tools and the Build Process     169
Using Source Control     169
  Types of Source Control     170
  A Process Example: Using a Distributed System     171
  A Second Process Example: Using a Distributed System     172
  A Third Process Example: Using a Centralized System     173
Understanding the Pros and Cons of Centralized Systems and Distributed Systems     173
  Consuming Shared Code from Others     173
  Sharing Code with Others and Reviewing Changes     174
  Backing up the Code     174
  Managing Check-in Frequency     175
  Managing Merge Conflicts     175
  Managing Control     176
  A Final Word About Pros and Cons     176
Evaluating a Hosting Service     176
  Using Apache Subversion (SVN)     177
  Using Microsoft Team Foundation Server (TFS)     177
  Using Git     179
Managing Features and Defects     179
  Managing Custom Workflow     180
  Managing Agile Development     180
  Managing Reporting     180
Using a Continuous Integration (CI) Build Server     181
Using Visual Studio 2010 Developer Tools     181
  Refactoring Tools in Visual Studio      182
  Third-Party Refactoring Tools     183
Summary     185
9  Cleaning Up Legacy Solutions     187
Organizing the File System     187
Structuring the Project      189
Working with Project Categories     190
Understanding Project Types     191
  Application-Agnostic Projects     192
  Generic UI Projects     192
  Model-agnostic Projects     193
  Model-specific Projects      193
Reengineering Project Recommendations     193
  Constants     194
  Data Transfer Objects (DTO) Projects      195 
  Interfaces     196
  Services     197
  Domain Model Projects     198
  Repository Projects     199
  Controllers, View Models, and Presenters     199
Refactoring to the Solution Structure     200
  Remove Unnecessary Using Clauses     200
  Separate Unit Tests and Integration Tests     201
  Move Classes to Appropriate Projects     202
  Move Shortcuts to Libraries     202
Refactorings that Affect Logic     203
  Move Initialization Logic into the Constructor     204
  Replace Nested IF Statements with Guards     205
  Removing Access to Entity Class Constructors     210
Summary     211
10  Establishing the Foundation     213
Adding New Projects     213
Using Prism, Unity, and Enterprise Library Versions     214
Adapting the Shell     216
  Creating the IBaseView     217
  Adapting the Current Shell     218
  Adding a Shell Controller     220
Creating the Service Locator     220
Setting Up the BootStrapper Class     223
  Creating the Winforms BootStrapper     223
  Updating the Winforms Program Class      226
  Creating a WPF Application and Bootstrapper     228
  Using Alternative Bootstrapper Configurations     232
Summary     236
11  Basic Refactoring to Services     237
Using DialogService     238
  Unit Testing     242
  Refactoring for DialogService     249
  Adding Unit Tests     250
Using LogWriterService     251
  Refactoring for LogWriterService     254
Tracking Session Information     257
  Refactoring for Session Information     258
Accessing Resources the SOA Way     260
  Refactoring for ResourceProvider     264
Using a Message Aggregator     265
  Refactoring for MessageAggregator     266
Converting Static Classes     271
Refactoring Static Classes     272
Summary     273
12  Advanced Refactoring to Services    275
Using a Repository Pattern     275
  Creating a Repository with a Domain Model     283
  Reengineering Methods to a Repository     288
  Converting Existing Code to Use a Domain Model     289
  Adding Data Validations to the Domain Model     291
  Reengineering Domain Models to Use Validations     296
Using a Generic Object Manager     296
Simplifying Complex Code with a Command Dispatcher Service     303
  Refactoring for CommandLineInterpreter     313
Summary     314
13 Refactoring to a Controller     315
Using the Legacy Approach to Form Creation     316
Preparing the View     319
Introducing the Controller     320
Enhancing the Controller     322
Summary     325
Appendix Reengineering .NET Projects with Visual Studio 2012     327
Examining Source Control with Visual Studio 2012     327
Managing Parallel Development     330
Making Changes in Isolation     334
Unit Testing with Visual Studio 2012     337
Writing a Unit Test Method     338
Running the Unit Test     339
Using the Edit-and-Continue Feature     341
Using Continuous Test Runner     344
Using Fakes to Write Unit Tests for “Untestable” Code     346
Looking for Hard-to-Maintain Code Using Code Metrics     348
Looking for Code Duplicates     350
Summary     353
Index     355

Purchase Info

Buy Access

ISBN-10: 0-13-296493-7

ISBN-13: 978-0-13-296493-7

Format: On-line Supplement

$49.99

You can purchase immediate access to this online product with a credit card.