5 Reasons to Quit and 5 Reasons to Stay

In 1977 the Apple II, TRS-80 and the Commodore PET were released. In the same year David Allen Coe wrote a song for Johnny Paycheck called Take This Job and Shove It. (listen on YouTube) The hit single sold over two million copies and inspired a movie by the same title. I have no doubt that it inspired a lot of people to quit their job and find something better.

image
(from the album image on Amazon)

I was entering junior high school then but having grown up on a farm with the radio tuned to country music, the tune and the words stuck. In my own career I have made the choice to quit or to stay a number of times. Early in my career I burned a bridge that I later regretted. Since then I have not left a job in a way that I have later come to regret, although I have sometimes come to regret leaving the job itself.

What then should you use as criteria for quitting a job or staying in a job where you are thinking about quitting? Obviously the answer to this question will be deeply subjective, so I want you to consider that you ought to make such a choice based on much more than my opinion or an old song. With that caveat in place, let's dive into my personal opinions.

Why Quit

  1. Unhappy -- This seems obvious. If you're unhappy, you might be in the wrong job. But before you hand in your resignation, ask yourself why you're unhappy. Maybe even consult with a professional. Is it really the job that is making you unhappy? Or is it something about yourself that you could change? If you find yourself in a toxic environment and you cannot alter it, save your sanity and get out.
  2. Bored -- The job is unchallenging. You find yourself more interested in checking Facebook than you do your work. You complete your tasks without struggle and without learning anything new. You spend more time wondering what you'll have for lunch than you do about how to complete your work.
  3. Starving -- If you are not getting paid what you need to pay the bills or achieve your financial goals, ask yourself if you could do better. The most likely answer is that you can if you are willing to take some risk. Those may be big IFs for you, so proceed with care. And if you find yourself stuck, perhaps you should think of getting more education or starting a business on the side.
  4. Unsatisfied -- While it may seem to be the same, this is not the same as being unhappy. You may enjoy your job and the people you work with immensely but you may find that you are still unsatisfied. This may be because you find your work lacking significance or purpose. You may feel as if you're not contributing value to the community you value. A friend told me recently that we ought to, "Do those things that last, not those things that should be last."
  5. More -- Finally one good reason, in my opinion, to quit your job is that you want more from your career. It may be that you want to work in a different place or industry. You may want to work with a company led by people of a different caliber or with different goals and principles that you more readily identify with. Perhaps you want to explore an entirely different line of work. My father used to tell me, when assigning me a new task on the farm and in response to my complaints of being too tired, "A change is as good as a rest." You may be perfectly satisfied in your job but yearn for a new adventure. Perhaps you are a content hobbit and a band of dwarves come along and entice you to join a new startup far away and over the mountains.

Why Stay

  1. Finishing -- You may have good reasons to leave but a compelling reason to stay is to finish what you've started. If you hate to leave things incomplete or you want to simply see your current project succeed, you can stuff all the reasons you want to or ought to quit into a box and get them out after you're finished. They'll likely still be there when you're done.
  2. Stability -- This is where you should do what I say and not what I do. Sometimes I have left a stable job for one of the above reasons and later have thought that I ought to have stayed and made my life less chaotic for myself and my family. Too many job changes in my career has at times been a barrier for potential hiring managers. Take care when you choose to quit. Sometimes staying for another year will open up greater opportunities down the road.
  3. Learning -- Often the reason we want to quit is exactly the reason we ought to stay. The challenges we face in a job provide an ongoing opportunity to learn and grow. Running away from that because it's hard is often, if not always, a mistake. If you believe that you have more to learn and contribute, it may be to your advantage to stick it out.
  4. Opportunity -- Many employers promote from within. Some do not. If you have future opportunities coming your way, or even a likelihood of such, it may be worth putting up with whatever is bothering you and kicking things up a notch to get noticed and get promoted. Patience and hard work nearly always pay off. On the other hand, I have watched a few of my peers stay in a job far too long and pass on opportunities for growth in a lateral move, falling behind in growth and financial rewards.
  5. Anchor -- Your interests in other areas of your life may require you to have an anchor, a job you can count on even if you are not entirely satisfied. You may be serving your community or writing a book or caring for children or another family member. If keeping a job that otherwise you might leave in order to fulfill this other part of your life is necessary, then find a way to be at peace with that decision. It's not wrong to need the anchor or to choose another priority over your career.

Making Up Your Mind

Sometimes it's an easy choice. Sometimes it's much harder. Keep in mind that it's easier to find a job when you have a job. Reach out to those in your life that you care about and that depend on you. Get their support for your decision if you can. Get their input. They may be seeing the next move on the chessboard from the sideline when you cannot.

Weigh the pros and cons. Don't let a recruiter pressure you into making a decision. Don't make a decision because you're angry or otherwise dealing with powerful emotions that could lead you into making a bad decision. Take your time. Make a decision and then move forward. Don't consider an offer from an employer to keep you unless the only reason you are leaving is financial, and even then, take care. Once you take another offer, be sure to stick with it.

Good luck!

HttpContext and Logging to Elasticsearch on a Background Thread

“HttpContext is not thread-safe. Reading or writing properties of the HttpContext outside of processing a request can result in a NullReferenceException.” (from docs.microsoft.com)

image

I am a big fan of Elasticsearch (ELK) logging and have built this into the Ioka.Services.Foundation using the Serilog libary, my current favorite .NET Core logging library. There are many ways to approach this and my intent is not to explore those but to show one way of taking on the task of logging in a background thread while preserving some request context detail in your log.

Following the recommendation on the above docs page, we copy the elements of the HttpContext that we need for our background thread logging using the LogContextFactory. Here’s a snippet of that code. For your scenario, you’ll want to modify what values you wish to preserve and you may wish to remove the fairly heavy duty user agent parser if you don’t care about seeing user agent data broken down in the log message.

public static LogContext Create(HttpContext context)
{
   return CreateFactory(() => context)();
}

public static Func CreateFactory(Func httpContextFactory)
{
   if (null == httpContextFactory) throw new ArgumentNullException(nameof(httpContextFactory));
   return new Func(() =>
   {
      try
      {
         var httpCtx = httpContextFactory();
         var httpRequestFeature = httpCtx.Request.HttpContext.Features.Get();
         var context = new LogContext();
         context["_ThreadId"] = Environment.CurrentManagedThreadId.ToString(); 
         context["_Source"] = Assembly.GetEntryAssembly().GetName().Name;
         context["_IpAddress"] = httpCtx.Connection.RemoteIpAddress.ToString();
         context["_UserId"] = httpCtx.Request.Headers["APPUID"].Count > 0 
            ? httpCtx.Request.Headers["APPUID"][0] 
            : context["_UserId"];
         context["_HttpMethod"] = httpCtx.Request.Method;

In the controller we call the Create method to get a copy of what we need to pass into the background thread async method called DoMathWithLogging (cheesy name for demo purposes only) like this:

public async Task<ActionResult<IEnumerable<string>>> Get()
{
    var msg1 = "Another message";
    var msg3 = new CustomError { Name = "Second", Message = "Second other message" };
    _logger.Debug("This is a debug message. {msg1}, {@msg3}", msg1, msg3);

    var logContext = LogContextFactory.Create(this.HttpContext);
    var result = await _mathDemoProvider.DoMathWithLogging(logContext, _logger);

    return new string[] 
    {
        logContext["_UserId"],
        logContext["_RequestId"],
        result.ToString()
    };
}

Now in the DoMathWithLogging method, we use the ILog interface With method to pass the LogContext object into the logger to preserve what we have copied from HttpContext to the LogContext object.

public async Task<long> DoMathWithLogging(LogContext logContext, ILog logger)
{
    long x = 0;
    try
    {
        var rand = new Random();
        for (int i = 0; i < 10; i++)
        {
            x = 1000 * (long)rand.NextDouble();
            Thread.Sleep(10);
        }
        Thread.Sleep(100);
        var c = 0;
        x = 77 / c;
    }
    catch (Exception e)
    {
        //uses new logger with saved context as this 
        //is not on the request background thread
        logger.With(logContext).Error(e, "Error: value of {LargeValue}", x);
    }
    return x;
}

Note that in our demo code, we deliberately throw a divide by zero error and log it. And now in the implementation of the With method looks like this, capturing the current thread in the “_ThreadId-With” property on the context.

public ILog With(LogContext context)
{
    context["_ThreadId-With"] = Environment.CurrentManagedThreadId.ToString();
    var list = _enrichers.Where(x => x.GetType() != typeof(LogEnricher)).ToList();
    list.Insert(0, new LogEnricher(context, null));
    return new Log(_config, _level, () => _index, _failureSink, _failureCallback, list.ToArray());
}

In the With method, we insert a new log enricher for the Serilog logger. This allows us to capture the copied context values in the log messages, such as the Error logged like this:

{
  "_index": "test",
  "_type": "logevent",
  "_id": "JAdXF2oB9fWPG6gy8H_9",
  "_version": 1,
  "_score": null,
  "_source": {
    "@timestamp": "2019-04-13T15:36:40.2296224+00:00",
    "level": "Error",
    "messageTemplate": "Error: value of {LargeValue}",
    "message": "Error: value of 0",
    "exception": {
      "Depth": 0,
      "ClassName": "",
      "Message": "Attempted to divide by zero.",
      "Source": "Ioka.Services.Demo",
      "StackTraceString": "   at Ioka.Services.Demo.Providers.MathLoggingDemoProvider.DoMathWithLogging(LogContext logContext, ILog logger) in D:\\Code\\Github\\Ioka.Services.Foundation\\src\\Ioka.Services.Demo\\Providers\\MathLoggingDemoProvider.cs:line 30",
      "RemoteStackTraceString": "",
      "RemoteStackIndex": -1,
      "HResult": -2147352558,
      "HelpURL": null
    },
    "fields": {
      "LargeValue": 0,
      "_UserId": "root",
      "_IpAddress": "::ffff:172.18.0.1",
      "_Source": "Ioka.Services.Demo",
      "_MachineName": "6cf7fdb5f3cf",
      "_ThreadId": "14",
      "_HttpMethod": "GET",
      "_RequestId": "50d32de9-df69-4aee-ae48-075f22b8ac2d",
      "_Url": "https://localhost:44370/api/Values",
      "_Query": "Microsoft.AspNetCore.Http.Internal.QueryCollection",
      "_WebUser": null,
      "_Browser": "Chrome 73.0.3683 Windows 10",
      "_Header_Connection": "keep-alive",
      "_Header_Accept": "text/plain",
      "_Header_Accept-Encoding": "gzip, deflate, br",
      "_Header_Accept-Language": "en-US,en;q=0.9",
      "_Header_Host": "localhost:44370",
      "_Header_Referer": "https://localhost:44370/api-docs/index.html",
      "_Header_User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36",
      "_ThreadId-With": "14"
    }
  },
  "fields": {
    "@timestamp": [
      "2019-04-13T15:36:40.229Z"
    ]
  },
  "sort": [
    1555169800229
  ]
}

Note the "_ThreadId-With" property above has the same vs!he as the request thread is. This is because not all async methods will run on a background thread. In previous versions of this code, I forced a long running task to spin up on another thread to verify this. Generally I would not recommend that in practice.

Also note the "_RequestId" property which would allow you to filter in Kibana for all entries with that value in order to trace all log entries for a given request. This can be a very useful tool when you're trying to figure out what happened.

This is the first of many upcoming posts on the code and use of the Ioka.Services.Foundation. The code base is not intended for production use but to provide a guide when you create your own internal libraries to spin up a set of .NET Core microservices that have a common set of fundamental elements that will make working on them, supporting them and using them easier.

How Photography Helps Me Be a Better Software Architect


arizonahighways

I want to share with you how my efforts to perfect my semi-commercial hobby of photography help me be a better software architect.

My first camera was a Kodak Pony 135. I had no idea what I was doing, but I learned a lot by experimenting with that camera. My first computer was a Commodore 64. I was only slightly more informed about computing, having learned BASIC on a Commodore PET over two years prior. Again through experimentation and reading every Creative Computing magazine that I could get my hands on, I learned much more about computing and programming.

So now you know that I've been doing photography and computing for longer than many of my colleagues in this business have been alive. Let's see if my insights are of any use to you.

Patterns in Composition

In photography one must always be aware of the composition of the shot. How do the elements of the shot work together to draw the eye to the subject, to the story you want to tell? Learning the rule of thirds can be quite useful in understanding that, as in photography, so too in software we must look for patterns of composition to focus the user experience on the desired outcome. These patterns are often not visible to the untrained eye, just as in photography our audience may not really know why they like the photo, but they do. Software users will know they love or hate the software, but only you will know they love it because you composed it using patterns that make the magic happen.

Following a Process

We rarely get something right the very first time we try it. We're more likely to get something right when we follow a process that has led to success in the past. In photography I have learned that I must follow a process of preparation, analysis, exploration, decision taking and execution. A well thought out process in software development is equally crucial to success.

Breaking the Rules Sometimes

Once you know the rules of your process and craft, you can begin to take some risks in breaking the rules to achieve a desired effect. Only after understanding the rule of thirds in photography and knowing how and why this rule will help you compose your shot in a way that will present your subject well can you begin to experiment with breaking that rule to tell a slightly different story. The same is true in software architecture. Knowing how the rules of SOLID and design patterns will help you achieve the best outcome is crucial. Only then can you begin to experiment with small deviations to the rules to find new an innovative ways to achieve your goals.

Knowing Your Subject

In photography one must know something about the subject of the photograph. The more you know about the subject, whether this is a person, a landscape, a flower or a bug, the better you will understand how to draw out the character of your subject in your photograph. Being a software architect means knowing your subject, your users, stakeholders, the data and systems and the processes needed to make things work. The more you know about that, the better your architecture and design will be and the happier your customer will be.

Best Tools Don't Always Make the Best Work

Some photographers believe they must have the best, most expensive equipment to achieve the greatest possible result. This just is not true. I once shot with a full frame camera and now shoot with a Micro Four Thirds. Some day I'll move to medium format for other reasons, so don't discount having great tools, but don't assume that without the best you cannot produce great work. The same is true in software. We do not always need the best IDE or the most powerful laptop or the biggest amount of RAM to achieve the best result. Indeed if one focuses only on the tools, one might overlook the fact that one's work is to produce something great with the tools you have. Focus on the finished product and whine less about the tools you have been given.

Always Something Beyond Your Control

In photography you cannot control the weather or an unruly portrait subject. You cannot decide when your SD card will fail. You cannot guarantee that every shot will be perfect. There are always elements of the work that are out of your control. To succeed one must embrace the unknown and unexpected. In software architecture this is also true. There are many aspects of a project which you will have the ability to control. Time and business demands are not among them. Resource availability or team skills are not always within your control. You must learn to embrace the things that are not under your control and work as well as you're able to achieve your goals in spite of these.

Try Again Tomorrow

When I'm shooting landscapes, I often think that I've nailed it only to learn in post processing my RAW images that I failed to capture what it was I thought that I had seen when I was in the moment. These failures fall to the digital cutting room floor and push me to go back out and try again. There is a reason we have iterative processes in software development. We don't always get it right. We must continue to hone our craft and work and rework until we do get it right. Even then there is always more we can do. Sometimes the most important aspect of courage is simply to say to oneself, "I'll try again tomorrow." (Taken from a favorite saying borrowed from a friend of mine who passed away recently.)

People and Love Are The Most Important Ingredients

In photography and software architecture and development, I have learned that the most important aspect and ingredient to success is people. The people we work with will come from many different backgrounds. They will have different needs and desires. We must learn to love them and work with them. Only when we do this can we achieve our greatest success because our success depends on their success. When you love the people with whom you work, you will want to see them succeed. You will be kind but honest. You will be patient but urge them to do their best work. You will put their needs ahead of your own. Miraculously you will produce your very best work and so will they.

How System.Net.Http 4.3.0 Ruined Everyone's Day

I have not updated the MessageWire library for about a year now. But it still works just fine. Mostly. New Year's resolution #1: Update MessageWire.

trustme

Dependency Hell

I'm cleverly using MessageWire to create a customized shared session service for a hybrid set of web applications that include old ASP.NET Web Forms running in .NET Framework 4.6.1 and newer, upcoming, web sites built on ASP.NET Core 2.0. So first it had to work with the older Web Forms site. And it did work. Very well. I'll share some of that fun code on another day in another post.

What did not go well is that my Web Forms site using a library that uses HttpClient in System.Net.Http to call an internal web service suddenly failed.

Here's the HTTP request before pulling MessageWire into the project.

POST http://localhost:53739/api/ProfileDetail HTTP/1.1
Accept: application/json
Content-Type: application/json; charset=utf-8
Host: localhost:53739
Content-Length: 592

{"Id": "…removed actual data…"}

And here's the same request after pulling MessageWire into the project with no other code changes.

POST http://localhost:53739/api/ProfileDetail HTTP/1.1
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Accept: application/json
Accept-Encoding: gzip, deflate
Host: localhost:53739
 
250
{"Id": "…removed actual data…"}
0

See the problem? Yikes, my web service was unable to deserialize the second request created with HttpClient v4.3.0, so of course, that led to a huge failure.

Everyone's Worst Nightmare

What's worst about this is that I did not know about this side effect and this code made it into production causing a nightmare during a critical moment of the day and the month. Of course we rolled it back to stop the bleeding, but damage was done and folks were not happy with me in the least. It took me the rest of the day to find the symptoms of the cause which precipitated the failure.

The fact that it took me so long felt like another failure. Even with the final discovery that the HTTP request was borked, I was clueless as to its exact cause. I even engaged several team members to pour through my code to find the problem with the code I had committed. They could not find it.

So today, with less pressure on, I began methodically thinking of it and tracing back the code that generates the HTTP request. Ultimately it came down to HttpClient in System.Net.Http. This led me to discover that pulling in MessageWire into my ASP.NET Web Forms application on .NET Framework 4.6.1 also pulled in the flawed System.Net.Http version 4.3.0 package.

Light bulb moment! Check for updates. Sure enough, there was a System.Net.Http 4.3.3 available. And boom goes the dynamite! The request was back to looking normal and working just fine with the service being called.

MS OSS Buyer Beware!

When you pull in any new NuGet package which brings with it some dependencies, be sure you check out any updates to those dependencies. Shocking as it may seem, even Microsoft's packages can contain nasty little bugs. And test your assumptions.

The Kids Make Our Christmas the Best

This Christmas has been a particularly joyful one. Despite one late evening lapse of patience, I can truly say this has been one of the most memorable celebrations of Christ's birth in my entire life. We were so pleased to have all of our children and two of our very good friends from India with us. Because of work schedules and other plans, we arranged to be visited by Santa Claus on the 24th and so today has become a quiet and peaceful reflective time. Of all the wonderful gifts I received this year, I want to share with you the one that touched me and my wife beyond any other.

Our children spent a day together on a recent weekend which they called "Sibling Day." It was not the first time this has happened. We are blessed with children who love each other and enjoy one another's company even now as adults. So Lorri and I suspected nothing. As we opened presents, going around taking turns as is our tradition, our children insisted that Lorri open one particular present last. I prevailed in having her open my gift last, but it paled in comparison to this one. It was a book and I've gathered their permission to share it here. I hope you'll indulge me then as I share with you a rather "social media" style personal post.

Tyler and Lorri

We have been married for thirty years. In that time we've seen a few ups and downs. I'm so grateful to have such a good wife by my side. She has been the anchor in my life against the tides and currents of changing and challenging times.

20171225_114631

This photo of Lorri and me was taken a few years ago by my sister Rebecca. She's a natural shutter bug.

20171225_114552

This one is the title page and was taken very recently. Both of us have lost a few pounds since the cover photo was taken. Lorri still looks younger and better than me. I'm the luckiest man alive.

The Kids Together

Jaelise, Johanna, John and Josh are four great kids. These re-enactment photos make us smile from ear to ear.

20171225_114522

20171225_114444

20171225_114410

20171225_114346

Josh

Our youngest and still living at home, Josh rarely had to be told to go to bed. Whenever he was upset with us, he would cover his head with a blanket or something and say, "You don't see me."

20171225_114309

20171225_114241

John

Our children were always fond of running around with no clothes. John was no exception. At four he learned to ride a bike and defied the rule of wearing a helmet, so he occasionally wore some road rash and once crashed hard enough to cause a severe concussion which had us in the ER for a while. Thankfully his skull was sufficiently strong and the damage was temporary. We think. (Just kidding, John.)

20171225_114210

20171225_114136

Lindsey

A little more than a year ago, Lindsey came into our lives. She and John were married in November 2016. She is a delightful addition to our family and we could not be more pleased for John.

20171225_114103

20171225_114033

Johanna

The cutest messy eater in our house, Johanna was always perplexed when Lorri knew she had been sneaking some treat or another because the evidence was always on her face.

20171225_114000

20171225_113923

Jaelise

A ham for the camera then and now, Jaelise always loved to dress up and her bunny was a favorite. Her kayak has taken its place and goes nearly everywhere with her now.

20171225_113845

20171225_113758

Jenessa

Reading the book and laughing at each page, when Lorri came to this page that laughter turned to tears for both of us as we remembered our oldest and most perfect child. Jenessa lived just nine days and as we remembered the birth of Christ, these pages reminded us poignantly of our first child's birth. The elephant named Ernie was a small stuffed rainbow colored elephant who was buried with Jenessa in 1988. While we miss her so much, she is and always will be a very important part of our family.

20171225_113648

20171225_113619

My Kids Are The Best

When they say, "It's the thought that counts," I believe it. My children are thoughtful, loving and kind. I love them so very much. They have made this Christmas one of the very best of my life!

20171225_113546

Special thanks goes to Johanna who made all this happen. What an amazing gift!

Don't Have a Merry Christmas

I once thought it strange that the British say, "Happy Christmas," when I grew up in America saying, "Merry Christmas!" But after some reflection, I think the Brits have it right.

2 Nephi 28:7
"Yea, and there shall be many which shall say: Eat, drink, and be merry, for tomorrow we die; and it shall be well with us."

The merry making we do at Christmas time has little to do with the true meaning of Christmas. Parties, food, music, drink and all the trimmings hide the real purpose of Christmas and provide no lasting happiness.

christmasparty

I do not mean to say that having a party and making merry is necessarily bad. Simply that it is not the best way we can celebrate the Christ child and make others happy and be happy. Indeed some of my most happy memories of Christmas are of cold wintery mornings driving the tractor to plow the neighbor's long driveway or doing some other act of kindness for a neighbor or friend.

Perhaps my warmest memory of such a time was a particularly cold and wintry Christmas morning when my brother and I got up very early on Christmas morning and snuck out of the house to milk the cow, feed the animals and bring in buckets of coal to keep the house warm. These chores were normally done by our dad who allowed us to play with our gifts while he did all of our chores on Christmas morning. I still remember his smile and the look of surprise and love on his face when we told him he did not need to go out that morning.

You can learn a little about the history of Merry Christmas vs Happy Christmas here:

Perhaps we can all learn something about being happy this Christmas rather than just making merry. Let us try to light the world with His happiness.

I know that true joy, true happiness comes in and through our Lord and Savior Jesus Christ.

Matthew 25:40
And the King shall answer and say unto them, Verily I say unto you, Inasmuch as ye have done it unto one of the least of these my brethren, ye have done it unto me.

Let us remember him by remembering our neighbor this year. In other words, have a Very Happy Christmas!

Allow Your Models to Cross Only One Boundary

Don't let your models cross more than one boundary. Sure there may be exceptions, but I haven't found one that justifies the loss of flexibility achieved when requirements change.

Some years ago I worked with a thoughtful and intelligent programmer named Nick. He convinced me that models, or data transfer objects (DTOs) should not cross more than one service or domain boundary. I was skeptical at first. It seemed like a lot of duplicated code.

He talked me into it. And the next time the business changed a requirement, which of course happens often in most software development shops, I became absolutely convinced. We added something to one model, changed the code that produced the model and the specific code that consumed the model without breaking all other users of other endpoints that used the underlying models and entity models or services that produced them.

Here's what it looks like in one implementation:

models

Of course, your own architecture may involve more boundaries than shown here. You may have a message queue or services bus. I believe the principle still applies.

The greatest advantage is that you have an abstraction layer at every boundary that allows you to move swiftly when you need to support changing requirements. And I've never met a company or set of software developers that do not deal with regularly changing business requirements.

This is a very opinionated post and if you balk at the notion at first, I urge you to at least give it a try. You will find that you can enforce separation of concerns. You will find that you can avoid having a dependency on a framework, such as Entity Framework, in your application server code or in your hard wired client code, the latter of which would need only a reference to your ViewModels assembly. (Assumes you are working in .NET but I believe the principles apply universally.)

You will find that in preventing your business logic from knowing anything about the implementation of the interface provided by the Models assembly, you are forced to inject the dependency and are thus free to replace the dependency with a different implementation or even a mock for unit testing.

The list of benefits is long and I've surely missed a few important ones, but you get my drift. I hope.

TIP: Use AutoMapper or something like it to help you with the tedium when transformations are an exact 1:1 match.

Getting Back on the Horse

I grew up on a farm and ranch driving tractors mostly but riding horses to herd cows and to play as often as was possible. It was an idyllic way to grow up. I was more of a farmer than I was a cowboy, but I loved old western movies, especially John Wayne, and idolized the American Cowboy and the cowboy way of life.

This painting by a family friend named Lynn E. Mecham reminds me of all that I love about cowboys.

cowboys_thumb2

I encourage you to visit his Facebook page for his gallery. He does amazing work.

As a young boy one of my favorite pastimes was to saddle up the horse and join a few of my friends in a game of tag on horseback in the cedar and sage brush hills above the small farm on which I grew up. Of course we knew nothing really about the politics surrounding the treatment of Native Americans. For us it was just a game.

On one of these occasions, I was riding my brother's mare Toots, a beautiful buckskin that looked very much like this.

toots_thumb1

I was an Indian. One of my friends was selected to be the Cowboy, the guy who had to catch one of us. I had Toots running through the sage brush and planned to ditch the Cowboy in a barrel turn around a large cedar tree coming up on my left. I pulled left on the reins at just the right moment and she juked left around the tree.

Suddenly I was laying on the sand on my back, pain throbbing in my chest and, for a moment, I was unable to breathe. The tree had a large branch sticking out right at my chest height from the saddle. I was not hurt badly. I found Toots looking back at me as if to say, "What happened to you?" I got back on after a few minutes and we continued playing.

I learned a valuable lesson that day. Even when you're in a hurry, be cautious when rushing into a place you've never before been. You might get knocked off your horse, but you'll probably survive.

Fast forward a few decades to this year. After surviving a health crisis in India, I'm now dressing like a cowboy to remind myself to work hard and take better care of myself. And I'm still "playing" with Indians. But in this case real Indians.

I work with two teams of wonderful developers and testers in the New Delhi area. I have spent a little more than a year working with them. I was enjoying myself so much that I forgot the lesson of my youth and traveled in July to work and have fun with my Indian colleagues.

funday2_thumb1

I nearly died in India after that fun day. I got knocked off my horse. It took several weeks to get back up, but I did. And I may come off my horse again, but like my dad always taught me, I will get back on. I hope you do too.