Tuesday, September 24, 2013

We’re not a software shop. Yes, you are.

One of the things that has bothered me over the course of my career is hearing statements like this:

“We’re not a software shop. We just make <product here>.”

The typical scenario for a statement like this is the “justification” of cutting corners on software development:
Since the company really does not develop software, it’s okay for all the other departments to come up with a project plan and how long it will take, then hand that date to the software development team. Never mind that the deadline is not enough time to produce a quality product; it’s just the software piece. It’s good project management to make the software team hurry and hit the deadline.

What’s worse, programmers even use this excuse. And the business loves that.

That is, until the business finds itself mired in constant support, production problems, using unreliable data, and feature enhancements taking longer and longer to complete. The business can think of their situation in these possible ways:

* This is normal. This is just how software development works. We have a lot of production issues, but our team works hard to constantly keep it running.

* The software development team used to be fast and good, but now they’re slow and write a lot of buggy software. They must not care as much as they used to. We need to push them even harder.

* We must have been approaching software development the wrong way. Let’s stop and analyze why things are this way, and see what we can do to develop software the right way.

That last bullet point is rare. Why? Because only companies that “get” software development would ask those questions. And those companies would have done it correctly in the first place. It can happen, though, if enlightened employees are hired during this process.

The first bullet point is an unfortunate situation. Things could be better, but no one sees it, and the business keeps moving, albeit at a slower and slower pace. This is just how things are.

The second bullet point is tragic. The software team has put themselves (yes, it’s their fault) in the terrible situation of having to hurry and create bad software, and for their efforts they are now not trusted by management. They’ll typically spend nights and weekends (and early mornings) fixing things, and adding new things, because that’s what it now takes to keep things running. And many times the development team will do this covertly, because they don’t want management to know that yet another problem occurred. In the end, the software team gets burned out trying to keep up this pace, or management replaces them with offshore developers.


When your company depends on the software that it writes to keep things running and profitable, I hate to break it to you, but you are indeed a software shop. You’re just not admitting it.

Tuesday, September 17, 2013

Deadlines as excuses for writing poor quality code? No.

Someone said this to me:

"We never get a chance to clean up ABC code or to refactor it.”

My reply:

The business will never explicitly give you that time. It’s up to you (indeed, all of us) as professional developers to not use deadlines as excuses. There is no deadline in the world that should cause a seasoned developer to duplicate code. It’s up to us, with a commitment to quality, to push back when we’re told to hurry. If we don’t do that, who will? It’s professional negligence to use deadlines as excuses. Most businesses think they have done good project management work if they get the developers to hurry and produce the end result more quickly. They don’t realize how much they’re hurting themselves in the long run by sacrificing maintainable code.


Many times deadlines are arbitrary guesses that folks came up with at the beginning of a project. They’re meaningless. They’re actually worse than meaningless because being forced to hit them is detrimental to quality. It’s okay to let the business know that the work won’t be done “on time.” Many developers think they’re trapped into hitting a deadline, when if they just did quality work, and explained the situation to the business, the “deadline” could be moved, or code could be time-boxed. Sacrificing quality, to the degree that I’ve seen in ABC code, should never be an option.

Thursday, August 8, 2013

scriptcs in Two Minutes

Want to say you've used scriptcs? Follow this post and you can say that in about two minutes.

(For the longer version, go here: https://github.com/scriptcs/scriptcs)

At a command prompt, run this:
@powershell -NoProfile -ExecutionPolicy Unrestricted -Command "iex ((New-Object Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%systemdrive%\chocolatey\bin
Then run this:
cinst scriptcs
That's it. Really. Now you can write C# at a command prompt:

C:\>scriptcs
scriptcs (ctrl-c or blank to exit)

> var message = "Hello, world!";

> Console.WriteLine(message);
Hello, world!

Want to save some C# and run it any time? Do this:

C:\Temp>copy con helloworld.csx
var message = "Hello, world!";
Console.WriteLine(message);

        1 file(s) copied.

C:\Temp>scriptcs helloworld.csx
Hello, world!

Note: I got an error when trying to run this at the root of the C: drive, so I just switched to my temp folder and it worked.

Enjoy!

Wednesday, July 24, 2013

An Alternative To Stacking Many KnownType Attributes

If you find yourself having to stack many KnownType attributes on a class that is sent over the wire for WCF communication, there is a slick alternative.

Instead of something like this:


You can specify a method to reflectively return all of the types for you:


And here is the GetDerivedTypes() extension method:


Now we no longer have to add new KnownType attibutes every time we have a new subtype. Nice, eh?

Sunday, June 9, 2013

Curriculum Vitae - Bob Horn

See latest online resume (Jan 2022):
https://app.enhancv.com/share/be066243?utm_medium=growth&utm_campaign=share-resume&utm_source=dynamic

Bob Horn
rhornjr@gmail.com

Last updated: 18-Aug-2021

Objective

I want to be really, really good at what I do, and I want to be happy doing it. I love learning and I love sharing what I've learned. I want others to be excited about getting better at what they do. I want to help others be that way.

Education

Master of Science - Business Information Technology
Walsh College, Troy, MI
GPA: 4.0

Bachelor of Science - Computer Information Systems
Walsh College, Troy, MI
GPA: 3.81

Work

Proliant: Senior Software Engineer
Paylocity: Programmer
MEDsys: Director of Information Technology
First Solar: Developer IV (developer and architect)
Metavante: Programmer Analyst Specialist (developer and release management)
Maximum Data: Software Development and IT Manager
Dantom Systems: Development Manager and Developer
Case Consulting Group: Accountant and Developer

Technical Experience

Languages: C#, HTML, ASP.NET MVC, JavaScript, CSS, TSQL
Platforms: Windows, Linux
Concepts: Software development, leadership, teaching, design, architecture, project management, web, architecture

Project Experience

Architect: solar power plant energy prediction
ScrumMaster: manufacturing project - Lot Traceability
Developer: Many projects over many years

Presentations

Pluralsight Audition Video on Polymorphism (2013)
Web Development (June, 2016)
SignalR (June, 2013)
Project Maintainability Analysis (measuring OOP, SOLID, best practices) (May, 2013)
Windows 8 and JavaScript (March, 2013)
Clean Code and Design Patterns (June, 2012)
Design Patterns and OOP (January, 2011)
Chain of Responsibility Design Pattern (2009)

Other Activities/Hobbies

Bloghttp://inaspiralarray.blogspot.com/
Open source project (Presto)https://presto.codeplex.com/
Readinghttp://inaspiralarray.blogspot.com/2013/04/books-ive-read-software.html
StackOverflow reputation of 10,000+http://stackoverflow.com/users/279516/bob-horn
CodeMash: 2011, 2012, 2013, 2014, 2015, 2016, 2017

Friday, May 24, 2013

Quick and Dirty ClickOnce Server

Disclaimer: This isn't necessarily the way a ClickOnce server should be set up. This is me doing the bare minimum, hacking around, just to get it up and running for someone to use quickly. If you're looking for best practice, go somewhere else.

On a server that was picked to be used as the ClickOnce server, create a folder to store the ClickOnce deployed application:

C:\ClickOnce\PrestoDashboard

Since I'm using AD authentication, I also set the security on the above folder to contain only those people that I wanted to access the app.

In the properties of the WPF app, set the location and then click Publish Now:



At this point I thought it would work, but I was getting errors when trying to access the location within my browser. So I set up a virtual directory in IIS:


I was getting an authorization error at this point, so I went into the Authentication properties of the virtual directory (screenshot above, right side) and enabled Windows Authentication.


Done:


Friday, May 17, 2013

WCF Security Issue - The target principal name is incorrect


profile for Bob Horn at Stack Overflow, Q&A for professional and enthusiast programmers
My WCF service was working when testing on my laptop. After deploying to a dev environment where the client/caller and server/WCF were on different machines, I got this error:

System.ServiceModel.Security.SecurityNegotiationException: A call to SSPI failed...System.ComponentModel.Win32Exception: The target principal name is incorrect
My situation is this:
Client (AD user) -> WCF Service (AD service account)
First, the solution. Two options:
  1. Instead of using the AD service account, use the Network Service account
  2. On the client, specify a dummy SPN
Why do these things work? Another blog post explained the situation nicely.

For option #1, the Network Service account has access to the host machine SPN. Because of this, Kerberos authentication can be used. When the AD service account is used (like my scenario), it doesn't have access to the host machine SPN, so Kerberos fails and we get the SSPI exception.

For option #2, if a dummy SPN is used, Kerberos authentication will fail, however in this case authentication will fall back to NTLM and succeed.

An example client config section, using identity, is shown here:

<identity>  <servicePrincipalName value="MySystem/Service1"/></identity>

It can also be done programmatically (second line):
var uri = new Uri(ConfigurationManager.AppSettings["serviceAddress"]);var endpointIdentity = EndpointIdentity.CreateSpnIdentity("");var endpointAddress = new EndpointAddress(uri, endpointIdentity);return _channelFactory.CreateChannel(endpointAddress);
If the client doesn't explicitly specify an identity, WCF will automatically create an identity using the host name in the Uri. If we are calling net.tcp://remotemachine1:port/MyService, the WCF client will use the machine name as the SPN, like this:

EndpointIdentity.CreateSpnIdentity("remotemachine1")

That's what will be used to call the service. When this happens, Kerberos authentication will fail, WCF will not fall back to NTLM, and we get the exception.

Sunday, April 21, 2013

Finding the Root Cause of WCF Exceptions

When setting up a WCF service, calls can fail for many reasons. The frustrating part is that we typically get a generic error:

The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:00:59.8380000'.

In order to find out exactly what was wrong, simply configure tracing, by placing this in the config file of the WCF service:


  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="traceListener"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData"c:\temp\Traces.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

Note: The above configuration is from http://msdn.microsoft.com/en-us/library/ms733025.aspx.

After trying the WCF call again, open Traces.svclog and find the activity in red:


After clicking on the activity, click on the description/error in the right window pane:


The bottom pane will show you exactly what's wrong:



Books I've Read - Software

There are 89 books listed below. Out of those 89, I have chosen the five that have had the most influence on my career, and that I consider the best of them all. These are in no particular order.

My Top 5

1. Agile Principles, Patterns, and Practices in C# [Martin]
2. Head First Design Patterns [Freeman, et al.]
3. Peopleware: Productive Projects and Teams [DeMarco, Lister]
4. Joel on Software [Spolsky]
5. The Mythical Man-Month [Brooks]


C#/.NET
  1. Programming C# 5.0 [Griffiths]
  2. C# in Depth [Skeet]
  3. Programming .NET Components [Lowy]
  4. Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries [Cwalina, Abrams]
  5. Effective C#: 50 Specific Ways to Improve Your C# [Wagner]
  6. C# Cookbook, 2nd Edition [Hilyard, Teilhet]
  7. Introducing .NET 4.0: With Visual Studio 2010 [Mackey]
  8. CLR via C#, Third Edition [Richter]
  9. Expert C# 2008 Business Objects [Lhotka]
  10. Programming .NET 3.5 [Liberty, Horovitz]
  11. Essential Windows Communication Foundation (WCF): For .NET Framework 3.5 [Resnick, et al.]
  12. MSDN (magazine) - many


Design/Practices
  1. The Mythical Man-Month [Brooks]
  2. Agile Principles, Patterns, and Practices in C# [Martin]
  3. Design Patterns [Gamma, et al.]
  4. Head First Design Patterns [Freeman, et al.]
  5. Clean Code: A Handbook of Agile Software Craftsmanship [Martin]
  6. The Pragmatic Programmer: From Journeyman to Master [Hunt]
  7. Refactoring: Improving the Design of Existing Code [Fowler, et al.]
  8. Code Complete: A Practical Handbook of Software Construction [McConnell]
  9. Applying UML and Patterns [Larman]
  10. Software Engineering: A Practitioner's Approach [Pressman]
  11. UML Distilled [Fowler]
  12. Pragmatic Unit Testing in C# with NUnit [Hunt, Thomas]
  13. Practices of an Agile Developer: Working in the Real World [Subramaniam]
  14. Head First Object-Oriented Analysis and Design [McLaughlin, et al.]
  15. Data Modeling Essentials, Third Edition [Simsion, Witt]
  16. The Object-Oriented Thought Process [Weisfeld]


Architecture

  1. Patterns of Enterprise Application Architecture [Fowler]
  2. Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions [Hohpe, Woolf]
  3. Service Design Patterns: Fundamental Design Solutions for SOAP/WSDL and RESTful Web Services [Daigneau]
  4. Microsoft® Application Architecture Guide
  5. Microsoft® .NET: Architecting Applications for the Enterprise [Esposito]
  6. The Process of Software Architecting [Eeles, Cripps]
  7. REST in Practice: Hypermedia and Systems Architecture [Webber, et al.]


Web

  1. JavaScript and jQuery [McFarland]
  2. Programming ASP.NET MVC 4 [Chadwick, et al.]
  3. HTML5 and CSS3 [Castro]
  4. HTML5: The Missing Manual [MacDonald]
  5. Silverlight 4 in Action [Brown]
  6. Head First Ajax [Riordan]
  7. Programming ASP.NET [Liberty, Hurwitz]

Leadership/Project Management
  1. Agile Project Management with Scrum [Schwaber]
  2. Succeeding with Agile: Software Development Using Scrum [Cohn]
  3. The Five Dysfunctions of a Team: A Leadership Fable [Lencioni]
  4. Leadership: Enhancing the Lessons of Experience [Ginnett, et al.]
  5. The Leadership Challenge [Kouzes, Posner]
  6. A Guide to the Project Management Body of Knowledge, Third Edition [PMI]
  7. Project Management: A Systems Approach to Planning, Scheduling, and Controlling [Kerzner]
  8. The Power of IT: Survival Guide for the CIO [De Sutter]
  9. Ship it! A Practical Guide to Successful Software Projects [Richardson, Gwaltney]
  10. Creating a Software Engineering Culture [Wiegers]
  11. Peopleware: Productive Projects and Teams [DeMarco, Lister]
  12. The Project Manager's MBA: How to Translate Project Decisions into Business Success [Cohen, Graham]
  13. Adventures of an IT Leader [Austin, et al.]
  14. What Got You Here Won't Get You There: How Successful People Become Even More Successful [Goldsmith, Reiter]
  15. Manage It!: Your Guide to Modern, Pragmatic Project Management [Rothman]
  16. CIO Survival Guide: The Roles and Responsibilities of the Chief Information Officer [Schubert]
  17. The First 90 Days: Critical Success Strategies for New Leaders at All Levels [Watkins]
  18. Harvard Business Review (magazine) - many
  19. Introduction to Information Systems Project Management [Olson]
  20. Earned Value Project Management [Fleming]
  21. Applied Software Project Management [Stellman, Greene]
  22. Introduction to Project Management [Schwalbe]

Other/Advice/Culture
  1. Big Ball of Mud [Foote, Yoder]
  2. Building Windows 8 Apps with JavaScript [Sells, Satrom]
  3. Building Windows 8 Apps with C# and XAML [Likness]
  4. C Programming Language [Kernighan, Ritchie]
  5. WPF 4 Unleashed [Nathan]
  6. Programming Entity Framework: Code First [Lerman, Miller]
  7. Joel on Software [Spolsky]
  8. More Joel on Software [Spolsky]
  9. The Best Software Writing I [Spolsky]
  10. Programming Language Pragmatics, Third Edition [Scott]
  11. Data Communications and Computer Networks: A Business User's Approach [White]
  12. Manufacturing Execution Systems (MES): Optimal Design, Planning, and Deployment [Meyer, et al.]
  13. Workflow Modeling [Sharp]
  14. The Data Warehouse Lifecycle Toolkit [Kimball]
  15. Computer Networks, Third Edition: A Systems Approach [Peterson, Davie]
  16. Statistics for Business and Economics, 6th Edition [Anderson, et al.]
  17. Information Nation: Seven Keys to Information Management Compliance [Kahn, Blair]
  18. Who: The A Method for Hiring [Smart, Street]
  19. The Guru's Guide to Transact-SQL [Henderson, Celko]
  20. Computing Concepts with Java 2 Essentials [Horstmann]

Linux

Saturday, April 13, 2013

An Implementation of the Dispose() Pattern - For Reference

Awesome SO answer on proper use of IDisposable here.

The Bad Code Problem - The Smooth-talking Garbage Guy


I think there is a major, fundamental problem in the software development industry. And it's a difficult, tricky problem to solve. That problem is managers hiring developers that write truly poor code, not knowing it, and letting them run amok, and even letting them guide other developers and teams.

The root of the issue is management not knowing the true quality of the programmers they hire. It's all too easy for a smooth-talking developer (that actually writes garbage code, hence smooth-talking garbage guy) to make himself look like the right answer in front of a manager that can't refute anything he says. It's especially more problematic when not examining a developer's code before a manager hires the developer. And even worse if a manager looks at the code and doesn't truly know if it's good code.

The problem is further compounded when misled manager guy (MMG) touts his developer to others within the organization. And to make matters even worse, the root of all evil in a company, the BOYM (bend over yes men) who are afraid to do or say anything about it.

Developers (and somewhat decent developers) can sometimes be awed by this STGG. I think I know why now. His systems are complex balls of mud, yet he can explain things in a way that can seem to make sense. Only through seeing through the bullshit, and going back to the basics of simple, clean, and elegant code, can you truly appreciate STGG for what he has built: an ugly system because he doesn't know how to do otherwise.

Good systems, regardless of architecture, have code that is simple, clean, and elegant. Period. A system with an awesome architecture, backed by terrible code, is a terrible system.

Bringing in a new developer, or architect, that knows how to do things better than the way things are currently being done, won't change things. At least not anytime soon. The system is the system, and the folks left to deal with it are constrained by it. In time, these new resources will look bad because they'll be associated with the current crop of problems. This is exasperating, especially if STGG has moved on/up to other departments.

How is this fixed? In enlightened companies this isn't even a problem. Software development is valued as a first-class citizen, and top-notch developers tend to run things. In unenlightened companies, it's almost impossible. The only thing I can think of is to hire an outside firm to do an objective analysis of the system. This can be expensive (although much, much less expensive than the hidden cost of not doing it at all), and since the system "works," nothing is usually done.

How do we stop this from happening?

Saturday, March 2, 2013

Inspecting Browser Requests and Server Responses with Fiddler

With Fiddler, not only can you inspect the browser requests, and the server responses, but you can alter them.

Note: To filter the traffic to only localhost, so Fiddler ignores other requests, do this (you need to click in the window on the left to get this to save):



In order to intercept a browser request to the server, turn on automatic breakpoints in Fiddler:


Note: You may not want to set automatic breakpoints until just before the actual request is sent. Otherwise, Fiddler will start breaking on all requests.

Make sure Fiddler is set to capture traffic:


Initiate a request. In this scenario, I'm running an app from Visual Studio and eventually hitting a save button, on a web page, to submit a request to the server. When I click the save button, Fiddler will break on the request. You can click on the request to view the data being sent.



This is what you'll see in the right pane of Fiddler:


In the above image, the top pane is the request details, and the bottom pane is the response details.

Saturday, February 2, 2013

Connecting SSMS to SQL Azure

When using SSMS to connect to a SQL Azure DB, some typical ways of connecting simply don't work.

Note: I believe I had this issue because I wasn't using SQL Server 2008 R2. That appears to be necessary for the normal login dialogs, and object explorer, to work.

The first issue is the connection dialog box. When you enter your information and hit connect:


You get this:


The way around this is to cancel the connection dialog and click the New Query button, in SSMS, even though you're not yet connected:


The same dialog box will come up, but this time you'll be able to connect. HOWEVER, when you try to select your DB:


You'll get this error:


Note: The USE statement won't work either.

To change the DB, do this:


You'll be presented with the same connect dialog as earlier. This time, click Options:


Select your DB here:


Now you're connected!

Note: You can select the DB, within options, when you first connected, after clicking New Query.