<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
<title type="text">Scott MacLellan</title>
<generator uri="https://github.com/mojombo/jekyll">Jekyll</generator>
<icon>http://www.smaclellan.com/favicon.png</icon>
<link rel="self" type="application/atom+xml" href="http://www.smaclellan.com/feed.xml" />
<link rel="alternate" type="text/html" href="http://www.smaclellan.com" />
<updated>2019-02-19T22:05:53-05:00</updated>
<id>http://www.smaclellan.com/</id>
<author>
  <name>Scott MacLellan</name>
  <uri>http://www.smaclellan.com/</uri>
  <email>scott@smaclellan.com</email>
</author>


<entry>
  <title type="html"><![CDATA[The Worst Week of My Life]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/the-worst-week-of-my-life/" />
  <id>http://www.smaclellan.com/posts/the-worst-week-of-my-life</id>
  <published>2016-06-07T13:55:00-04:00</published>
  <updated>2016-06-07T13:55:00-04:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;In January I had the worst week of my life. My wife and I joked we wanted to
start 2016 in February. Within a single week I lost my job and we had a miscarriage.
In this post I want to tell you about this traumatic experience, how this
massive change has turned out positive and what I learned from it.&lt;/p&gt;

&lt;h1 id=&quot;before&quot;&gt;Before&lt;/h1&gt;

&lt;p&gt;I started this year with all the optimism in the world. Throughout the holidays
leading up to 2016, I tried to refocus myself. The year started with new
habits and influences which improved my outlook on life. I was determined to be
more positive and work hard at doing a great job.&lt;/p&gt;

&lt;p&gt;This was a stark contrast to the previous several months which were filled with ups and downs.&lt;/p&gt;

&lt;p&gt;My time with the &lt;a href=&quot;/posts/exterminator/&quot;&gt;Exterminators&lt;/a&gt; was a blast. I felt re-energized
and excited about software development again. While with the team I found new
growth areas and doubled down on existing skills. This left me wanting more.&lt;/p&gt;

&lt;p&gt;Returning to my previous team was jarring. When I left I was excited about a
new project which would have a huge impact. Incorrectly, I thought I would
get to dive into it right away. After I had started prototyping portions of it,
the whole project was given to another team.&lt;/p&gt;

&lt;p&gt;Instead, I was relegated to ongoing
maintenance on a different project. My learning slowed. Shortly afterwards our team split in two.
Another project I was excited about went with the other half of the team. I
felt like I had been punted to the B team. My heart was not
in my work. &lt;a href=&quot;/posts/exterminators-2-focus-and-quality/&quot;&gt;Focus and quality&lt;/a&gt; suffered.&lt;/p&gt;

&lt;p&gt;In the months leading up to January I was contemplating a larger change. The
essential question was whether I could still have an impact in my job or company.
Getting things done was frustrating and I did not deal
with this well. Over time my morale eroded further as I considered
greener pastures elsewhere.&lt;/p&gt;

&lt;p&gt;However, during a company-wide developer conference and the holidays I started to see
life differently. In my role
I might have plateaued, but I realized &lt;a href=&quot;http://d2l.com&quot;&gt;D2L&lt;/a&gt; as a whole still has many
great things to offer. I worked with phenomenal
people like Craig and &lt;a href=&quot;http://www.smaclellan.com/tags/#daryl&quot;&gt;Daryl&lt;/a&gt; whom I could still learn from. D2L operates on a large scale and have different
challenges which are exciting. Lastly, I fully believe in D2L’s &lt;a href=&quot;http://www.d2l.com/about/&quot;&gt;mission&lt;/a&gt; of transforming learning.&lt;/p&gt;

&lt;figure class=&quot;image-center&quot;&gt;
	&lt;img title=&quot;Starting January differently.&quot; alt=&quot;A picture of my desk with a small lego statue celebrating my 5 years at D2L.&quot; src=&quot;http://www.smaclellan.com/images/5-years-small.jpg&quot; /&gt;
	&lt;figcaption&gt;A fantastic gift from the D2L developer conference celebrating my 5 years there.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;In January I hit the ground running. I reset my perspective. I was excited again. Each task I worked on
received my complete attention. I was crushing it again. Coming to work each day was fantastic. We had
great projects lined up and we were making a difference.&lt;/p&gt;

&lt;h1 id=&quot;terminus&quot;&gt;Terminus&lt;/h1&gt;

&lt;p&gt;The company mentioned there might be some changes come later in the month. In
the past our team had been completely immune. After all, our team was doing
critical work which could dramatically improve how the company operates. I
considered myself an important contributing member of team and in my
hubris didn’t think anything of it.&lt;/p&gt;

&lt;p&gt;On that fateful January 26th, my manager who seemed a little choked up came and
got me at my desk. This was not like him. I felt a pang of fear, then it happened. My time at D2L
was finished. I was given the paper work, told the terms and then escorted
to a conveniently located exit nearby.&lt;/p&gt;

&lt;p&gt;I was absolutely stunned. It was difficult to speak. On my way out I bumped
into one of my mentors and could barely tell them what happened. It took
everything to stop myself from crying.&lt;/p&gt;

&lt;p&gt;We had planned our life out around my job. This was one thing I thought I could
depend on. I had worked there for over 5.5 years. In the previous few years we
bought a house and had our son, Jude. How were we going to afford everything?
Even in our wildest contingencies we were
not ready for me to lose my job. The news was overwhelming.&lt;/p&gt;

&lt;p&gt;Then the second bombshell went off. My wife was expecting our second child. She
was having signs things were not right. The day after I was let go we
lost the baby. Even months later, I am immediately brought back to the
devastation we felt. All we could do was hold each other and cry. As I write
this I am crying again as the memories come flooding back.&lt;/p&gt;

&lt;figure class=&quot;image-center&quot;&gt;
	&lt;img title=&quot;Although we never knew you, we still love you.&quot; alt=&quot;A commemorative necklace my wife wears for the miscarriage.&quot; width=&quot;640&quot; src=&quot;http://www.smaclellan.com/images/angel-necklace.jpg&quot; /&gt;
	&lt;figcaption&gt;A commemorative necklace my wife wears for the miscarriage.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;This was the worst week of my life.&lt;/p&gt;

&lt;h1 id=&quot;doubt&quot;&gt;Doubt&lt;/h1&gt;

&lt;p&gt;You are your own worst enemy. I spent too much of the next few months rethinking everything. Was there
something I did? Something I didn’t do? Why was I chosen? Not knowing why is
perhaps the hardest part.&lt;/p&gt;

&lt;p&gt;Even now I doubt myself. Have I been a &lt;a href=&quot;http://www.hanselman.com/blog/ImAPhonyAreYou.aspx&quot;&gt;phony&lt;/a&gt; for all these years? Am I
a horrible programmer or worse? There is an interesting cognitive bias known as the &lt;a href=&quot;https://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect&quot;&gt;Dunning-Kruger&lt;/a&gt;
effect where the truly incompetent cannot possibly know how bad they are. They
lack the meta-thinking to understand their own faults. In short, you can be so
bad you don’t realize it. Is that me?&lt;/p&gt;

&lt;p&gt;I talked a little bit about my self-doubts in my post
‘&lt;a href=&quot;/posts/are-you-your-code-reviews/&quot;&gt;Are you your code review?&lt;/a&gt;’. They have always been with me. This event fanned the flames of those
doubts even more.&lt;/p&gt;

&lt;p&gt;Leading up to the exit interview I wrote lists
of things which I thought might have led to this outcome.
Talking to my former boss helped clear up my
lists. He highlighted areas for improvement and made me feel like I
was not a failure.&lt;/p&gt;

&lt;p&gt;Getting past my self-doubt and focusing on moving forward was the first step.
This easily becomes a dark line of thinking which only leads to self-destruction.&lt;/p&gt;

&lt;h1 id=&quot;acceptance&quot;&gt;Acceptance&lt;/h1&gt;

&lt;p&gt;Our family took the first week to recover and get back to normal. There was no changing
what had happened. Daily life was permanently altered. We needed to accept this new reality and move forward.&lt;/p&gt;

&lt;figure id=&quot;josh&quot; class=&quot;image-center&quot;&gt;
	&lt;img title=&quot;Oh, hello there.&quot; alt=&quot;A very large picture of Josh's face upside down.&quot; width=&quot;480&quot; src=&quot;http://www.smaclellan.com/images/josh.jpg&quot; /&gt;
	&lt;figcaption&gt;Oh Josh, you are so silly.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;During those first few days the weirdest thing that I needed to accept was my
coworkers were suddenly not there. Waking up every morning I was confronted
with the fact that I would not be seeing Travis and Josh today. Many of my
coworkers had grown into close friends on whom I rely a great deal. I was always
happy to see them again or beat them at foosball. Our relationship would need
to change if it was to survive.&lt;/p&gt;

&lt;p&gt;Another odd thought experiment was the other choices D2L
could have made. Was I chosen instead of other people? Would me
staying mean someone else leaving? In the end I felt it was
better that I was chosen instead
of someone else. Better I go through this than one of my friends. After our life
had normalized a bit, I was optimistic we would be okay and didn’t want them to
have the same burden.&lt;/p&gt;

&lt;p&gt;Although being asked to leave was not great, it did open the door for new
opportunities. With our last several projects I had been dipping my toes into
different technologies and was really enjoying it. Now I had the chance to make
a bigger shift in my career.&lt;/p&gt;

&lt;h1 id=&quot;searching&quot;&gt;Searching&lt;/h1&gt;

&lt;p&gt;Getting a job in the past was a fairly straight forward process:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Write a resume&lt;/li&gt;
  &lt;li&gt;Find jobs&lt;/li&gt;
  &lt;li&gt;Write cover letters&lt;/li&gt;
  &lt;li&gt;Apply&lt;/li&gt;
  &lt;li&gt;Interview&lt;/li&gt;
  &lt;li&gt;Repeat or accept the offer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This time around everything happened at the same time and looked like:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Network, find jobs and apply all at once&lt;/li&gt;
  &lt;li&gt;Interview&lt;/li&gt;
  &lt;li&gt;Review and accept offers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;During this job hunt I learned how invaluable your connections are in finding new jobs. Over the years I had
worked with many different people who had moved on from D2L to other companies.
I had great role models at D2L who were willing to be references.&lt;/p&gt;

&lt;p&gt;Thanks to my &lt;a href=&quot;https://ca.linkedin.com/in/smaclell&quot;&gt;network&lt;/a&gt;, finding potential jobs changed dramatically.
The first step in my search was to talk to my connections. Right away I was introduced
to potential companies. I went for coffee to learn about open positions. Casual
meetings turned into interviews.&lt;/p&gt;

&lt;figure class=&quot;image-center&quot;&gt;
	&lt;img title=&quot;Seriously. My profile exploded overnight.&quot; alt=&quot;A graph of my linked in profile getting tonnes of traffic.&quot; width=&quot;480&quot; src=&quot;http://www.smaclellan.com/images/linkedin-traffic.png&quot; /&gt;
	&lt;figcaption&gt;Suddenly leaving a company does wonders for your LinkedIn profile.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Finding potential jobs in Kitchener-Waterloo is also extremely easy thanks to
services through Communitech. They run an active &lt;a href=&quot;https://www.waterlootechjobs.com/jobs/&quot;&gt;job board&lt;/a&gt; which
has hundreds of fantastic postings available. I found many interesting
companies with a diverse range of sizes and needs.&lt;/p&gt;

&lt;p&gt;A number of recruiters reached out with various opportunities. While I did
not use their services, they showed me positions typically outside of my
existing network. They helped restore my confidence that I would be able to find
a new job and move past my doubts.&lt;/p&gt;

&lt;p&gt;Resumes and cover letters are a must. Within the first week I had mine updated
and was ready to share it with the world. It slowly got better over time with
more and more feedback. Luckily, I had updated it sporadically with different
achievements and milestones.&lt;/p&gt;

&lt;p&gt;Interviews are intimidating. It had been over 5 years since I last
interviewed at all. Co-op terms at university gave me a lot of practice, but
without using those skills for years I found I was very rusty. My friends
helped me through mock interviews to get me ready. Even still, I bombed a
few of them which was tough.&lt;/p&gt;

&lt;p&gt;Regardless of how an interview went I always sent a follow up email to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Thank the interviewer&lt;/li&gt;
  &lt;li&gt;Emphasize what went well&lt;/li&gt;
  &lt;li&gt;Address any hiccups&lt;/li&gt;
  &lt;li&gt;Reiterate why I would be a great fit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Due to my background I am less good at algorithms and get caught up on some standard interview
questions. I spent a lot of time practicing interview problems and reading up on
&lt;a href=&quot;https://www.amazon.com/Introduction-Algorithms-Thomas-H-Cormen/dp/0262033844&quot;&gt;algorithms&lt;/a&gt;. When that wasn’t enough I tried learning Ruby and refreshing
my knowledge of JavaScript frameworks/idioms. After coming home from interviews, I implemented
the programming questions I was given to double check my solutions.&lt;/p&gt;

&lt;h1 id=&quot;success&quot;&gt;Success&lt;/h1&gt;

&lt;p&gt;Things started slowly then picked up pace. At first I just had coffee with
former colleagues/mentors. Interviews started to trickle in and then really
accelerated. During the last week I had a flurry of final interviews leading
up to a difficult choice.&lt;/p&gt;

&lt;p&gt;In the final stages I was fortunate to have several offers from great companies.
Each presented different opportunities and challenges. I don’t think I could
have gone wrong choosing from any of the options. Other interviews were not successful
and I will need to try again another time.&lt;/p&gt;

&lt;p&gt;Over the weekend I made my decision. Due to
the timing I had another week off to relax and decompress before starting work.
The end was in sight after the harrowing month which preceded it.&lt;/p&gt;

&lt;p&gt;On March 7&lt;sup&gt;th&lt;/sup&gt; I started working at &lt;a href=&quot;https://www.vidyard.com/&quot;&gt;Vidyard&lt;/a&gt; full time!
Even before the first day I was blown away by the amazing culture. They were
so welcoming and helped me get connected right away. On my second day I pushed
code to production! I am thrilled to be part of the team.&lt;/p&gt;

&lt;h1 id=&quot;lessons&quot;&gt;Lessons&lt;/h1&gt;

&lt;p&gt;What may have been the worst week of my life at the time, will now be the start
of a bigger change in my life. This entire experience has taught me so much and
helped me understand what matters most.&lt;/p&gt;

&lt;p&gt;At D2L, I poured a lot of time, effort and self-worth into my job, only to see it come to
an end. I was slowly learning work should not be my #1 priority. This
experience brought that realization painfully to the forefront.&lt;/p&gt;

&lt;figure class=&quot;image-center&quot;&gt;
	&lt;img title=&quot;I love you both.&quot; alt=&quot;My wife and cute son hugging.&quot; width=&quot;480&quot; src=&quot;http://www.smaclellan.com/images/ange-and-jude.jpg&quot; /&gt;
	&lt;figcaption&gt;These are the people I care about most.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;What really matters is our relationships and loved ones. The quiet moments as a family during
the first week will stay with me forever. I cannot thank enough the many friends
and family members who supported us through this challenging period. We are so
fortunate to have them in our lives.&lt;/p&gt;

&lt;p&gt;We needed to accept what had happened to move on. Hopefully some day we will
have other children. I found another job. We can learn from our past, but
should not dwell on it.&lt;/p&gt;

&lt;p&gt;Interviewing is a skill you need to keep practicing. From now on I plan on
regularly interviewing and updating my resume so I will not become rusty again.
The goal is not to job hop every year. Instead, I want to understand what
people are looking for and be able to confidently present myself.&lt;/p&gt;

&lt;p&gt;I was due for a change and believe I have found what I needed. While my time at
D2L was a great learning experience, I was restless and wanted something else.
During several low points while at D2L I had felt like leaving. I was never
able to make the choice on my own and now the choice was made for me.&lt;/p&gt;

&lt;h1 id=&quot;epilogue&quot;&gt;Epilogue&lt;/h1&gt;

&lt;p&gt;Why write this post now? I am finishing my probation and feeling more
comfortable at Vidyard. After the event I was so shaken up I decided to put the
blog on hold. Starting a new job I wanted to make sure my first 3 months were
solid.&lt;/p&gt;

&lt;p&gt;Well, mostly solid. Almost immediately after starting I was sick for a full 3
weeks. In the first month I worked
from a bed at home more than I did at the office. Although I was sweating
bullets while coughing up lung chunks, my manager was extremely supportive. My
coworkers all told me not to worry and how later I could look back and laugh
about it. I had their trust to do what I needed to do and the space to get
better. The entire experience was yet another testament to why Vidyard is
awesome.&lt;/p&gt;

&lt;p&gt;Now, I have shipped a few features and am working on something bigger. It has
been a blast. I feel like I have learned so much in very little time.
Hopefully, in the coming weeks I will be able to share what I have learned
with you.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Thanks to my former co-worker &lt;a href=&quot;#josh&quot;&gt;Josh&lt;/a&gt; for helping me with the grammars.
Sorry for turning down your edit about who wins our foosball.
Thanks for the many years we spent together at D2L. I miss you canoe buddy.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I would like to thank my lovely wife &lt;a href=&quot;http://macangela.tumblr.com&quot;&gt;Angela&lt;/a&gt; for helping review this
post. I would be lost without you. I love you.&lt;/em&gt;&lt;/p&gt;

</content>
</entry>


<entry>
  <title type="html"><![CDATA[Vanilla JS Tetris - Good Luck, Have Fun]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/vanillajs-tetris-gl-hf/" />
  <id>http://www.smaclellan.com/posts/vanillajs-tetris-gl-hf</id>
  <published>2016-01-31T07:05:07-05:00</published>
  <updated>2016-01-31T07:05:07-05:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;It has been quite the week. Sometimes you need to just relax.
Try this simple &lt;a href=&quot;http://www.smaclellan.com/vanillajs-tetris/&quot;&gt;Tetris clone&lt;/a&gt; made with only the best Vanilla JS.
Good luck, have fun.&lt;/p&gt;

</content>
</entry>


<entry>
  <title type="html"><![CDATA[How to Self-Host Nancy Without Locking Your DLLs: Shadow Copying]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/self-hosted-nancy-with-shadow-copy/" />
  <id>http://www.smaclellan.com/posts/self-hosted-nancy-with-shadow-copy</id>
  <published>2016-01-12T17:11:07-05:00</published>
  <updated>2016-01-12T17:11:07-05:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;This is in response to a GitHub &lt;a href=&quot;https://github.com/NancyFx/Nancy/issues/2123&quot;&gt;issue&lt;/a&gt; for &lt;a href=&quot;http://nancyfx.org/&quot;&gt;Nancy&lt;/a&gt;. The user is trying to
self-host Nancy without locking their DLLs. One easy way to do this is
to create a wrapper program which runs the actual program with shadow copying assemblies.
No DLLs are locked and the changes are minimal.&lt;/p&gt;

&lt;p&gt;I will first show a simple application which self-hosts Nancy and can serve a
request to &lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;/&quot;&lt;/code&gt;. The program will start listening, wait for a key to be
pressed and then exit. This is the code:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Nancy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Nancy.Hosting.Self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Program&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;http://localhost:12345&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;host&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;NancyHost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DefaultNancyBootstrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Now listening, have fun!&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ReadLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We will add a simple &lt;code class=&quot;highlighter-rouge&quot;&gt;NancyModule&lt;/code&gt; so we can test the application at &lt;code class=&quot;highlighter-rouge&quot;&gt;http://localhost:12345/&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Nancy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HelloWorldService&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NancyModule&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;HelloWorldService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AsText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello World&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This program will work as is. The problem is that it locks any assemblies it references.&lt;/p&gt;

&lt;p&gt;To work around this problem, add another executable to wrap the actual
implementation. In order to keep the DLLs unlocked, we will run the implementation from
a separate &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/2bh4z9hs(v=vs.110).aspx&quot;&gt;AppDomain&lt;/a&gt; with &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms404279(v=vs.110).aspx&quot;&gt;Shadow Copying&lt;/a&gt; enabled.&lt;/p&gt;

&lt;p&gt;AppDomains are a very powerful feature of
the Common Language Runtime for isolating code. They can use different security
contexts, modify how assemblies are loaded and can be managed independently.
There can be multiple AppDomains within a single process and can achieve some
of the same isolation benefits as processes.&lt;/p&gt;

&lt;p&gt;Using the separate AppDomain allows us to set the &lt;code class=&quot;highlighter-rouge&quot;&gt;ShadowCopyFiles&lt;/code&gt; option to &lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;true&quot;&lt;/code&gt;. This option will cause the
assembly loading process to copy each assembly into a different directory and then load them from the new location.
The local copies are left unlocked. For more information on &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms404279(v=vs.110).aspx&quot;&gt;Shadow Copying Assemblies&lt;/a&gt; refer to MSDN.&lt;/p&gt;

&lt;p&gt;The whole solution would look like the diagram below:&lt;/p&gt;

&lt;figure class=&quot;image-center&quot;&gt;
	&lt;img src=&quot;http://www.smaclellan.com/images/wrapper-executable.jpg&quot; alt=&quot;The wrapper executable calling the actual program to run it&quot; /&gt;
&lt;/figure&gt;

&lt;p&gt;This is the wrapper program to call the actual executable &lt;code class=&quot;highlighter-rouge&quot;&gt;Implementation.exe&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Program&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;AppDomainSetup&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setup&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AppDomainSetup&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;ShadowCopyFiles&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;true&quot;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// This is key&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;domain&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AppDomain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateDomain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Real AppDomain&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setup&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Execute your real application in the new app domain&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;domain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ExecuteAssembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;Implementation.exe&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;That is all there is to it. Don’t want your DLLs to be locked? The easy solution
is to use another AppDomain with Shadow Copying enabled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;All the code for this blog post can be found in this &lt;a href=&quot;https://github.com/smaclell/NancyShadowAssemblies&quot;&gt;sample project&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

</content>
</entry>


<entry>
  <title type="html"><![CDATA[Introduction to Dependency Injection]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/introdution-to-dependency-injection/" />
  <id>http://www.smaclellan.com/posts/introdution-to-dependency-injection</id>
  <published>2016-01-08T05:33:07-05:00</published>
  <updated>2016-01-08T05:33:07-05:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;I had the privilege of mentoring several co-workers in 2015. One of the
topics they found confusing was Dependency Injection. We use it everywhere. To
them it felt like magic. The code just fits together through mystical Containers.
In this post we will break down the powerful concepts surrounding
Dependency Injection.&lt;/p&gt;

&lt;p&gt;Let’s start with some simple classes:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello {0}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Bar&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;m_foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Example&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;m_foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;World&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;These are all concrete classes. No fancy dependency magic
here. What this code does is very clear. &lt;code class=&quot;highlighter-rouge&quot;&gt;Bar&lt;/code&gt; creates a &lt;code class=&quot;highlighter-rouge&quot;&gt;Foo&lt;/code&gt; then
uses it to print &lt;code class=&quot;highlighter-rouge&quot;&gt;Hello World&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A complete program using this code is also straightforward:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Program&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Example&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Create a new &lt;code class=&quot;highlighter-rouge&quot;&gt;Bar&lt;/code&gt; then call &lt;code class=&quot;highlighter-rouge&quot;&gt;Example&lt;/code&gt;. Hello World!&lt;/p&gt;

&lt;h1 id=&quot;dependency-inversion-principle-applied&quot;&gt;Dependency Inversion Principle Applied&lt;/h1&gt;

&lt;p&gt;Let’s spice things up! Instead of creating the &lt;code class=&quot;highlighter-rouge&quot;&gt;Foo&lt;/code&gt; in &lt;code class=&quot;highlighter-rouge&quot;&gt;Bar&lt;/code&gt;’s
constructor we can pass it in. Better yet, we can switch to an interface with
all the same methods as &lt;code class=&quot;highlighter-rouge&quot;&gt;Foo&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IFoo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IFoo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello {0}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Bar&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;IFoo&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IFoo&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;m_foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Example&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;m_foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;World&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So what have we gained? Well, the low level &lt;code class=&quot;highlighter-rouge&quot;&gt;Bar&lt;/code&gt; class no longer knows
anything about the &lt;code class=&quot;highlighter-rouge&quot;&gt;IFoo&lt;/code&gt; implementation it is using. That is now up to
callers using &lt;code class=&quot;highlighter-rouge&quot;&gt;Bar&lt;/code&gt;. We have switched from a concrete implementation to a higher level abstraction.
This decouples the code making it easier to maintain.&lt;/p&gt;

&lt;p&gt;We have applied the &lt;a href=&quot;http://www.objectmentor.com/resources/articles/dip.pdf&quot;&gt;Dependency Inversion Principle&lt;/a&gt;&lt;a href=&quot;#di-note-1&quot;&gt;&lt;sup id=&quot;reverse-di-note-1&quot;&gt;1&lt;/sup&gt;&lt;/a&gt;.
As defined by &lt;a href=&quot;https://twitter.com/unclebobmartin&quot;&gt;Robert Martin&lt;/a&gt; it is:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A. High level modules should not depend upon low level modules. Both should depend upon abstractions.&lt;/p&gt;

  &lt;p&gt;B. Abstractions should not depend upon details. Details should depend upon abstractions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;https://lostechies.com/derickbailey/2008/10/20/dependency-inversion-abstraction-does-not-mean-interface/&quot;&gt;The abstraction could be anything&lt;/a&gt;. Typically it will be an
interface, but can also be a base class, delegate or another abstraction. The key
is shifting the code from the implementation to a higher level.&lt;/p&gt;

&lt;h1 id=&quot;what-about-dependency-injection&quot;&gt;What About Dependency Injection?&lt;/h1&gt;

&lt;p&gt;Another concept closely related to Dependency Inversion is Dependency Injection.
In fact, we used it without really knowing it. Where Dependency Inversion was
all about the abstractions and layers, Dependency Injection is all about how
dependencies are provided.&lt;/p&gt;

&lt;p&gt;Don’t worry, it is a really simple idea. Here is the demystified definition by &lt;a href=&quot;http://www.jamesshore.com/Blog/Dependency-Injection-Demystified.html&quot;&gt;James Shore&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Dependency injection means giving an object its instance variables.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Literally, injecting dependencies into a class. In our previous example, we
injected our dependencies using constructor parameters. This is the
most common approach, but you can also inject dependencies using properties or specialized methods.&lt;/p&gt;

&lt;p&gt;Look look at the program from the last example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Program&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;IFoo&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Boom, IFoo injected!&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Example&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We inject the &lt;code class=&quot;highlighter-rouge&quot;&gt;IFoo&lt;/code&gt; into the constructor of the &lt;code class=&quot;highlighter-rouge&quot;&gt;Bar&lt;/code&gt;. The program can
now choose which &lt;code class=&quot;highlighter-rouge&quot;&gt;IFoo&lt;/code&gt; to use. This is more flexible than when the choice
was buried in the &lt;code class=&quot;highlighter-rouge&quot;&gt;Bar&lt;/code&gt; class.&lt;/p&gt;

&lt;h1 id=&quot;the-benefits&quot;&gt;The Benefits&lt;/h1&gt;

&lt;p&gt;We have inverted our dependencies and injected them
into our classes. This is fantastic! Our code is nicely decoupled. We can
easily change what is injected for testing or introducing new features.&lt;/p&gt;

&lt;p&gt;Implementations are hidden
behind abstractions and can be easily replaced. Want an &lt;code class=&quot;highlighter-rouge&quot;&gt;IFoo&lt;/code&gt; which writes
out to files? No problem. You can change the code to your new &lt;code class=&quot;highlighter-rouge&quot;&gt;FileFoo&lt;/code&gt; without ever
modifying &lt;code class=&quot;highlighter-rouge&quot;&gt;Bar&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The original &lt;code class=&quot;highlighter-rouge&quot;&gt;Bar&lt;/code&gt; is impossible to test in isolation. The direct dependency
on &lt;code class=&quot;highlighter-rouge&quot;&gt;Foo&lt;/code&gt; forces the two classes to be tested together. Changes to &lt;code class=&quot;highlighter-rouge&quot;&gt;Foo&lt;/code&gt;
could break the tests for &lt;code class=&quot;highlighter-rouge&quot;&gt;Bar&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By injecting the dependencies, we can use a fake &lt;code class=&quot;highlighter-rouge&quot;&gt;IFoo&lt;/code&gt; in
tests to do whatever we want. This is a great way to set up specific scenarios and/or avoid external
systems (i.e. databases or services).&lt;/p&gt;

&lt;h1 id=&quot;dependencies-for-everyone&quot;&gt;Dependencies For Everyone!&lt;/h1&gt;

&lt;p&gt;Creating classes is more challenging when you use Dependency Injection and
Dependency Inversion frequently.&lt;/p&gt;

&lt;p&gt;We have moved where dependencies are created. This poses a problem for
consumers of the original classes. They must both choose what to inject and
create all the dependencies. I mean &lt;em&gt;ALL&lt;/em&gt; the dependencies.&lt;/p&gt;

&lt;p&gt;Your dependencies start to have their own dependencies. While this is not too bad with
a few dependencies, once you get into chains of dependencies it gets nasty.&lt;/p&gt;

&lt;p&gt;Think about it. One class has a dependency, the
dependency has more dependencies and those dependencies have their own dependencies.
This is the tip of the iceberg:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;n&quot;&gt;SqlConnection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SqlConnection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;connection string&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;FooRepository&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;repository&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FooRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connection&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;Logger&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConsoleLogger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;BazService&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;BazService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;repository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If every class repeated setups like this it would be a big problem. Creating anything
would be a nightmare. Thankfully there is a better solution, Dependency Injection Containers.&lt;/p&gt;

&lt;h1 id=&quot;dependency-injection-containers&quot;&gt;Dependency Injection Containers&lt;/h1&gt;

&lt;p&gt;With all this dependency madness we need to find a better way to create classes.
Don’t worry! There are fantastic libraries to address
this problem. They are commonly referred to as Dependency Injection Containers
or Containers for short.&lt;/p&gt;

&lt;p&gt;Containers contain and seamlessly connect all of your dependencies. Within your
application they are used to instantiate dependencies they know about.&lt;/p&gt;

&lt;p&gt;Before we get to the real thing I want to walk you through a mental
models for Containers.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Externally they are like one massive Factory for any type&lt;/li&gt;
  &lt;li&gt;Internally they are like a Dictionary of Factories&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;enter-the-factories&quot;&gt;Enter the Factories&lt;/h3&gt;

&lt;p&gt;A Factory is a common creational pattern. They allow you to abstract
what is being created and how it is created. Dependency Injection Containers
behave like Super Factories which can create any type they know about.&lt;/p&gt;

&lt;p&gt;Want an &lt;code class=&quot;highlighter-rouge&quot;&gt;IFoo&lt;/code&gt;? Use the &lt;code class=&quot;highlighter-rouge&quot;&gt;FooFactory&lt;/code&gt;!&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FooFactory&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IFoo&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConsoleFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConsoleFoo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IFoo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello {0}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The Factory can be used any time an &lt;code class=&quot;highlighter-rouge&quot;&gt;IFoo&lt;/code&gt; is needed without any knowledge of which &lt;code class=&quot;highlighter-rouge&quot;&gt;IFoo&lt;/code&gt; is created.
We could easily update the &lt;code class=&quot;highlighter-rouge&quot;&gt;FooFactory&lt;/code&gt; to create a &lt;code class=&quot;highlighter-rouge&quot;&gt;FileFoo&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FooFactory&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IFoo&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FileFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FileFoo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IFoo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AppendAllText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;C:\\foo.txt&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hola &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Factories can partially contain the sprawling dependencies. The more
dependencies you have the more factories you will need. Factories will need
to call other factories to create nested dependencies. This can get
complicated when many dependencies are needed. The extra classes and glue code
are tedious to maintain.&lt;/p&gt;

&lt;p&gt;Prior to using &lt;code class=&quot;highlighter-rouge&quot;&gt;IFoo&lt;/code&gt; we need to create one using the factory:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Program&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;FooFactory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FooFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;IFoo&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Example&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Having to use the factory everywhere is not fun. We can do better.&lt;/p&gt;

&lt;h3 id=&quot;poor-mans-dependency-injection-container&quot;&gt;Poor Man’s Dependency Injection Container&lt;/h3&gt;

&lt;p&gt;What if we could use a single class to get any dependency we wanted?
We could use a Dictionary of Factories! The Dictionary would be keyed on types
where the values would define how to create their respective types.
We could then create any class the Dictionary knows about.&lt;/p&gt;

&lt;p&gt;In this section, we are going to create a really simple class to do just
that. Our very own simple Dependency Injection Container.&lt;/p&gt;

&lt;p&gt;Question: Why is it called a “Container”? It will contain all our application’s dependencies.
When our application starts we will give it all the dependencies we want to
create and classes we want to inject the dependencies into.&lt;/p&gt;

&lt;p&gt;The Container needs to:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Resolve types our application needs&lt;/li&gt;
  &lt;li&gt;Register types our application provides&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Enough with the words! Onto the code!&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ISimpleContainer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Resolve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Not bad. One method to &lt;code class=&quot;highlighter-rouge&quot;&gt;Register&lt;/code&gt; dependencies and another to &lt;code class=&quot;highlighter-rouge&quot;&gt;Resolve&lt;/code&gt;
them. The methods line up with our “Factory for any type” and “Dictionary of Factories” mental models.
We accept &lt;code class=&quot;highlighter-rouge&quot;&gt;Func&amp;lt;T&amp;gt;&lt;/code&gt;’s as simple factories for each type. Once all the types
have been registered, &lt;code class=&quot;highlighter-rouge&quot;&gt;Resolve&lt;/code&gt; behaves like a Factory for any type.&lt;/p&gt;

&lt;p&gt;Let’s implement our simple version:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SimpleContainer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ISimpleContainer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dictionary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Delegate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_registrations&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dictionary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Delegate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Resolve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m_registrations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)];&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;m_registrations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Internally we have the “Dictionary of Factories”. &lt;code class=&quot;highlighter-rouge&quot;&gt;Resolve&lt;/code&gt; uses the
&lt;code class=&quot;highlighter-rouge&quot;&gt;Func&amp;lt;T&amp;gt;&lt;/code&gt;’s we registered.&lt;/p&gt;

&lt;p&gt;Using the Container is easy. In the next example, we register all the types (lines 5-11)
then resolve them (lines 8 and 13). Once we have resolved &lt;code class=&quot;highlighter-rouge&quot;&gt;Bar&lt;/code&gt; we can use it normally!&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Program&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;SimpleContainer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SimpleContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConsoleFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;IFoo&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Resolve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Resolve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Example&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Cool. We have a Container. I would not use it in a real project. It is awkward
to use. The classes need to be wired together manually. We had to tell it
exactly how to create a &lt;code class=&quot;highlighter-rouge&quot;&gt;Bar&lt;/code&gt; even though it already knew how to
create an &lt;code class=&quot;highlighter-rouge&quot;&gt;IFoo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is where real Dependency Injection Containers are fantastic. They solve
the wiring problem and automatically inject dependencies they know about.
We can use the Container like glue to bind everything together.&lt;/p&gt;

&lt;p&gt;Abstractions are registered as concrete types. Consumers can resolve and use
those abstractions directly. They have no knowledge of the concrete types being
injected. Instead they rely on the Container. This preserves the Dependency
Inversion principle and helps decouple our code.&lt;/p&gt;

&lt;h3 id=&quot;awesome-containers&quot;&gt;Awesome Containers&lt;/h3&gt;

&lt;p&gt;Thankfully, there are many great open source Dependency Injection Containers.
The following three are my favourites. Our team has used them on different projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://autofac.org/&quot;&gt;Autofac&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Autofac is new, super clean and powerful. The registration
API is fun! They also have great support for
controlling &lt;a href=&quot;http://autofac.readthedocs.org/en/latest/lifetime/index.html&quot;&gt;lifetimes/scoping&lt;/a&gt; and &lt;a href=&quot;http://autofac.readthedocs.org/en/latest/lifetime/disposal.html&quot;&gt;cleaning up for you&lt;/a&gt;.
This would be my first choice when starting a new application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://structuremap.github.io/&quot;&gt;StructureMap&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;StructureMap is battle hardened having been the original .NET Dependency Injection
Container. The latest version of StructureMap was a massive step forward. The authors
incoperated many improvements they learned from 10 years of supporting the project.
A great choice you should definitely check out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/grumpydev/TinyIoC/wiki&quot;&gt;TinyIoC&lt;/a&gt; via &lt;a href=&quot;http://nancyfx.org/&quot;&gt;Nancy&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Lastly, we use Nancy a lot! For the simpler applications, we exclusively use the
built-in TinyIoC. It is simpler than the other Containers and is missing some
advanced options. We periodically consider switching to one of the other
libraries for these features which we believe would simplify our configuration.&lt;/p&gt;

&lt;h3 id=&quot;more-out-of-the-box&quot;&gt;More Out of the Box&lt;/h3&gt;

&lt;p&gt;These libraries greatly enhance how you register and resolve components.
Often these capabilities are connected; features used
when registering define how objects are resolved.&lt;/p&gt;

&lt;p&gt;All the Containers can wire together classes based on what they need injected. You could
register &lt;code class=&quot;highlighter-rouge&quot;&gt;Bar&lt;/code&gt; and when it is resolved the Container would automatically
inject an &lt;code class=&quot;highlighter-rouge&quot;&gt;IFoo&lt;/code&gt; based on what was registered for &lt;code class=&quot;highlighter-rouge&quot;&gt;IFoo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here is an example of our application using Autofac:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Autofac&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Program&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ContainerBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ContainerBuilder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RegisterType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ConsoleFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;As&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RegisterType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AsSelf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;IContainer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Resolve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Example&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;It does the right thing and gives &lt;code class=&quot;highlighter-rouge&quot;&gt;Bar&lt;/code&gt; the registered &lt;code class=&quot;highlighter-rouge&quot;&gt;ConsoleFoo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Many Containers have shortcuts for simple transformations, i.e. from &lt;code class=&quot;highlighter-rouge&quot;&gt;T&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;Lazy&amp;lt;T&amp;gt;&lt;/code&gt;.
Containers often support resolving/registering open generic types.&lt;/p&gt;

&lt;p&gt;Containers can offer the ability to register sets of dependencies in
&lt;a href=&quot;http://autofac.readthedocs.org/en/latest/configuration/modules.html&quot;&gt;Modules&lt;/a&gt; or &lt;a href=&quot;http://structuremap.github.io/registration/&quot;&gt;Registries&lt;/a&gt;. This provides a simple
way to group registrations together or split them apart. For example, you could
register all database related classes in one module separate from your logging
module.&lt;/p&gt;

&lt;p&gt;Most Containers provide mechanisms
for registering your types based on conventions so you do not
need to configure everything by hand. You can register all classes
implementing a similar interface name, i.e. &lt;code class=&quot;highlighter-rouge&quot;&gt;Foo&lt;/code&gt; would be registered
for &lt;code class=&quot;highlighter-rouge&quot;&gt;IFoo&lt;/code&gt;. This is cool for people who like conventions over configuration,
but can be too much magic other people. We use this approach and only configure
classes which violate our simple conventions.&lt;/p&gt;

&lt;p&gt;Perhaps the greatest benefit is how they integrate with various frameworks.
Containers often have shortcuts to hook into popular web frameworks, like ASP.NET MVC or
Nancy. The framework can use the Container to resolve types it needs. We use this to create
Controllers and automatically inject their dependencies. This lets you use Dependency
Injection while decoupling your code from the Container itself. Everything
magically fits together.&lt;/p&gt;

&lt;p&gt;The larger our applications become the more benefit we get from using Dependency Injection
Containers. We no longer worry about how we are going to wire our classes together. Instead, we can
focus on designing our interfaces and classes.&lt;/p&gt;

&lt;h1 id=&quot;connecting-the-dots&quot;&gt;Connecting the Dots&lt;/h1&gt;

&lt;p&gt;Phew, you made it this far! I hope this helped shed some light on Dependency
Injection and the surrounding concepts.&lt;/p&gt;

&lt;p&gt;Instead of using concrete classes we switched to higher level dependencies,
applying Dependency Inversion. We needed to get those dependencies from
somewhere so we used Dependency Injection, via constructor parameters, to inject the
dependencies we wanted.&lt;/p&gt;

&lt;p&gt;We explored Dependency Injection Containers using these mental models:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Externally they are like one massive Factory for any type&lt;/li&gt;
  &lt;li&gt;Internally they are like a Dictionary of Factories&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then we dug into complete Dependency Injection Containers and their extra features.&lt;/p&gt;

&lt;p&gt;Have fun decoupling your dependencies!&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;further-reading&quot;&gt;Further Reading&lt;/h3&gt;

&lt;p&gt;There is so much more you can read and learn. While writing this post I found
these additional resources:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://autofac.readthedocs.org/en/latest/index.html&quot;&gt;Autofac&lt;/a&gt; and &lt;a href=&quot;http://structuremap.github.io/documentation/&quot;&gt;StructureMap&lt;/a&gt; Documentation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Both these libraries are fantastic and their maintainers have put some serious
work into writing comprehensive documentation. They share many recommendations
and pitfalls for using their frameworks. The most interesting articles include
insights into the decisions they made and why they made them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://lostechies.com/jimmybogard/2008/09/12/some-ioc-container-guidelines/&quot;&gt;Container Guidelines&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dependency Injection Containers impact how you design your application and need
to be treated with care. These recommendations will help you
avoid problems&lt;a href=&quot;#di-note-2&quot;&gt;&lt;sup id=&quot;reverse-di-note-2&quot;&gt;2&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://martinfowler.com/articles/dipInTheWild.html&quot;&gt;DIP in the Wild&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Real life applications of Dependency Injection in the wild plus a good recap of
the concepts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://www.martinfowler.com/articles/injection.html&quot;&gt;Inversion of Control Containers and the Dependency Injection pattern&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a more in-depth explanation of the concepts. The
closely related ideas of “Inversion of Control” and “Service Locators” are explained.
There is a review of best practices and trade-offs. Some of the best practices may be
a little dated, i.e. using a Service Locator instead of Dependency Injection Containers.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;footnotes&quot;&gt;Footnotes&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;#reverse-di-note-1&quot;&gt;&lt;span id=&quot;di-note-1&quot;&gt;1.&lt;/span&gt;&lt;/a&gt; I could not get this link to work. I found it
via &lt;a href=&quot;https://lostechies.com/derickbailey/2008/10/20/dependency-inversion-abstraction-does-not-mean-interface/&quot;&gt;this&lt;/a&gt; great article explaining how an abstraction is not synonymous with interfaces.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;#reverse-di-note-2&quot;&gt;&lt;span id=&quot;di-note-2&quot;&gt;2.&lt;/span&gt;&lt;/a&gt; For some applications we intentionally call
the Container from our tests. We treat the Container configuration as part of our integration tests. I will
agree this is not ideal, but it simplifies creating various types and better mimics what our users will run.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;thanks&quot;&gt;Thanks&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Thanks to my gracious 2015 mentees for letting me practice this on you.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks again to my co-worker Josh who helped review this article. He had the
great recommendation of renaming the “Poor Man’s DI Container section” to
“Man with too much time on his hands’ DI Container”. Maybe I need to go write
more code.&lt;/em&gt;&lt;/p&gt;

</content>
</entry>


<entry>
  <title type="html"><![CDATA[Rock-Solid PowerShell Projects]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/rock-solid-powershell-projects/" />
  <id>http://www.smaclellan.com/posts/rock-solid-powershell-projects</id>
  <published>2015-12-30T18:45:07-05:00</published>
  <updated>2015-12-30T18:45:07-05:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;We write a lot of PowerShell. We didn’t realize it when we started, but our
projects have gotten much bigger. What seemed like a small bit of glue scripting is now
the core project. As the projects grew we learnt some lessons in how to keep
them maintainable.&lt;/p&gt;

&lt;p&gt;Our first release was really simple. It was just enough to meet our project
goals. We didn’t think through how the different pieces would fit together. Fast
forward 2 years and the older projects felt very thrown together.&lt;/p&gt;

&lt;p&gt;When we started a new project I wanted to make it feel like a professional software
project. Instead of the &lt;em&gt;good enough&lt;/em&gt; we had with the first project, I wanted
everything to fit together just right. I want to apply all the best practices
we use with any other development. Just being glue was not enough.&lt;/p&gt;

&lt;p&gt;This list might seem straightforward and mundane. That is okay! I think these
guidelines are
essential for any project worth your time to maintain. With a looser
language like PowerShell, these conventions helped give our new project even more
structure. Ultimately, they led to better code we can all understand.&lt;/p&gt;

&lt;h3 id=&quot;consistent-layout&quot;&gt;Consistent Layout&lt;/h3&gt;

&lt;p&gt;At first, we tossed our files in one big
directory and a bunch of messy dot sourced files. This was brutal. Finding
anything was impossible.&lt;/p&gt;

&lt;p&gt;Now we have all entry scripts at the root of the project, all modules in a
&lt;code class=&quot;highlighter-rouge&quot;&gt;lib&lt;/code&gt; folder and &lt;code class=&quot;highlighter-rouge&quot;&gt;tests&lt;/code&gt; on their own. More folders are added as needed.
A consistent layout for files makes it easy to find your way around.&lt;/p&gt;

&lt;p&gt;We took this even further. We applied the same basic layout to all the projects and
libraries we maintain. Every repository now includes a build file, release notes and a &lt;code class=&quot;highlighter-rouge&quot;&gt;README.md&lt;/code&gt;
in addition to consistent directories. New developers (or you after &lt;a href=&quot;/posts/i-volunteer-as-tribute/&quot;&gt;4 months away&lt;/a&gt;) can
open any project and start contributing right away.&lt;/p&gt;

&lt;h3 id=&quot;test-thoroughly&quot;&gt;Test Thoroughly&lt;/h3&gt;

&lt;p&gt;We were naive when we started our first project. What the
project did was really simple. As a result, we thought all we needed to do was
run the code once through the happy path. As the code grew this was no longer enough.&lt;/p&gt;

&lt;p&gt;We now diligently test each module independently using &lt;a href=&quot;https://github.com/pester/Pester&quot;&gt;Pester&lt;/a&gt; then again with more
comprehensive integration tests together. Pester is
an amazing testing library for PowerShell. We love Pester. If you have not used it, go check
it out now.&lt;/p&gt;

&lt;p&gt;Pester has greatly improved our unit testing. Our previous testing
only validated large scenarios and missed the edge cases.
We now test individual functions in isolation to expose more permutations
caused by the lower levels.&lt;/p&gt;

&lt;h3 id=&quot;modules-for-everything&quot;&gt;Modules for Everything&lt;/h3&gt;

&lt;p&gt;Initially, any reusable functions were placed in magical &lt;code class=&quot;highlighter-rouge&quot;&gt;library.ps1&lt;/code&gt; scripts, which
would be dot sourced in every other script (i.e. &lt;code class=&quot;highlighter-rouge&quot;&gt;. $PsDir\library.ps1&lt;/code&gt; everywhere, boo). Everything was written as a script to
either be dot sourced or directly called. This was great when we started but
did not scale as the project became more complex.&lt;/p&gt;

&lt;p&gt;With newer projects we place everything into independent modules. Each
module has a single responsibility, i.e. setting up
part of our application. This keeps every module small and focused.&lt;/p&gt;

&lt;p&gt;Within each module, we intentionally keep some functions private. This allows us
to shrink the module’s surface area without losing functionality. With
our included scripts this would not have been possible.&lt;/p&gt;

&lt;h3 id=&quot;mandatory-continuous-integration&quot;&gt;Mandatory Continuous Integration&lt;/h3&gt;

&lt;p&gt;From the beginning, our projects
have had the ability to check them out, run all tests and publish releases.
This allowed us to rapidly add functionality while keeping up our basic hygiene. The
code remains clean and we can make sure it always meets our basic requirements.&lt;/p&gt;

&lt;p&gt;As we continued to improve, most of our projects have added &lt;a href=&quot;/posts/preflights-changed-our-world/&quot;&gt;Preflights&lt;/a&gt;.
This complemented our existing continuous integration. Now we stop
problems from ever reaching our master branch.&lt;/p&gt;

&lt;p&gt;Our added emphasis on testing at various levels has improved our
confidence. Every build/test run covers even more of the application and
edge cases.&lt;/p&gt;

&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;

&lt;p&gt;We have learnt a lot from maintaining PowerShell projects over the past few years.
Our new projects are rock-solid. We try to have the following in every project:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Consistent Layout&lt;/li&gt;
  &lt;li&gt;Thorough Testing&lt;/li&gt;
  &lt;li&gt;Single Responsibility Modules&lt;/li&gt;
  &lt;li&gt;Continuous Integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This has made our projects easier to understand and update.&lt;/p&gt;

&lt;p&gt;Have your glue scripts turned into something bigger? Is it time to take it to
the next level?&lt;/p&gt;

</content>
</entry>


<entry>
  <title type="html"><![CDATA[No Managed-Only Finalizers]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/no-managed-only-finalizers/" />
  <id>http://www.smaclellan.com/posts/no-managed-only-finalizers</id>
  <published>2015-12-28T18:55:07-05:00</published>
  <updated>2015-12-28T18:55:07-05:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;We cleaned up a fruity issues caused by using &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.object.finalize(v=vs.110).aspx&quot;&gt;.NET Finalizers&lt;/a&gt; with managed classes.
Finalizers are a magical method called by the Garbage Collector. Like most
magic you need to be careful or you might saw your legs off.
While Finalizers might sound like a cool way to clean up after yourself they should
 only be used to cleanup unmanaged resources. Otherwise, they are not recommended
and can lead to instability.&lt;/p&gt;

&lt;p&gt;There are two primary mechanisms for cleaning up resources in .NET:
Finalizers and &lt;code class=&quot;highlighter-rouge&quot;&gt;IDisposable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finalizers are meant to ensure unmanaged resources are cleaned up by the
Garbage Collector. They feel like a hold over from unmanaged code and I get
uncomfortable when I see them. In 99.9% of the managed code I have worked in they
don’t belong.&lt;/p&gt;

&lt;p&gt;Whereas most .NET classes implement the &lt;code class=&quot;highlighter-rouge&quot;&gt;IDisposable&lt;/code&gt; interface to tidy up
after themselves. Closing database connections and cleaning up files are
standard examples. The interface works great for allowing your consumers clean
up resources when they want to instead of waiting for the Garbage Collector.&lt;/p&gt;

&lt;p&gt;We were using Finalizers and were doing it wrong.&lt;/p&gt;

&lt;h1 id=&quot;what-went-wrong&quot;&gt;What went Wrong&lt;/h1&gt;

&lt;p&gt;With Finalizers, like their C++ sibling destructors, it is important to pay
attention to how objects are connected. We ran into a problem where a Finalizer
was disposing the object which created it.&lt;/p&gt;

&lt;p&gt;The classes &lt;code class=&quot;highlighter-rouge&quot;&gt;TestData&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;TestUtility&lt;/code&gt; were used together in integration
tests to setup/cleanup data. The tests intermittently failed because the
&lt;code class=&quot;highlighter-rouge&quot;&gt;DataWeCareAbout&lt;/code&gt; was deleted when the &lt;code class=&quot;highlighter-rouge&quot;&gt;TestData&lt;/code&gt; Finalizer ran.&lt;/p&gt;

&lt;p&gt;Our classes looked roughly like this (minus a bunch of boring code):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TestData&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TestHelper&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_helper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TestData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TestHelper&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;helper&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;m_helper&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;helper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// The Bad Finalizer&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;TestData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;m_helper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Dispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TestHelper&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IDisposable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TestData&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CreateData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TestData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Dispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;m_conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;DELETE DataWeCareAbout WHERE Id = @Id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Since Finalizers are called directly by the Garbage Collector the failures
were not consistent. They would happen if the Garbage Collector ran early in
the test run. We eventually found it by stepping through the code to isolate
what was deleting the data during the test. This led us to the Finalizers.&lt;/p&gt;

&lt;p&gt;Daryl, a great developer I work with, insisted Finalizers should not be used
with only managed code. Their sole purpose is to ensure unmanaged resources can
be cleaned up even if the programmer forgets.&lt;/p&gt;

&lt;p&gt;We had two problems:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;TestData&lt;/code&gt; disposed the &lt;code class=&quot;highlighter-rouge&quot;&gt;TestUtility&lt;/code&gt; which deleted &lt;code class=&quot;highlighter-rouge&quot;&gt;DataWeCareAbout&lt;/code&gt; too soon&lt;/li&gt;
  &lt;li&gt;We should not have used a Finalizer at all&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;finding-more-finalizers&quot;&gt;Finding More Finalizers&lt;/h1&gt;

&lt;p&gt;We looked through our code base to see if more Finalizers were used elsewhere. We
only found one where it was needed and many others which needed to be removed.&lt;/p&gt;

&lt;p&gt;The extra Finalizers were not needed at all! They had no unmanaged resources!
We deleted them without a second thought.&lt;/p&gt;

&lt;p&gt;As an added bonus, they were using a fun pattern which mixes Finalizers and &lt;code class=&quot;highlighter-rouge&quot;&gt;IDisposable&lt;/code&gt;.
Consumers can proactively call &lt;code class=&quot;highlighter-rouge&quot;&gt;Dispose&lt;/code&gt; and clean up the data. If that is
forgotten then the Finalizer will be used. This was complete overkill for the Finalizers
we didn’t even need.&lt;/p&gt;

&lt;p&gt;You can read more about this pattern and implementing Finalizers on &lt;a href=&quot;https://msdn.microsoft.com/library/b1yfkh5e(v=vs.100).aspx&quot;&gt;msdn&lt;/a&gt;.
For completeness here is a sample of the pattern based on our code/msdn:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Example&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IDisposable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_disposed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ScaryUnmanagedResource&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_resource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Example&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;m_resource&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ScaryUnmanagedResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Example&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Dispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Dispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Dispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;GC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SupressFinalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Dispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;disposing&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_disposed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Only if explicitly disposing should you clean up unmanaged resources&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// We don't have any so there is no work to be done&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// if( disposing ) {&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//}&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Clean up all unmanaged resources&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;m_resource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;learning-more&quot;&gt;Learning More&lt;/h1&gt;

&lt;p&gt;It turns out having a &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.object.finalize(v=vs.110).aspx&quot;&gt;Finalizer&lt;/a&gt; makes classes special. Here are a few
highlights which further convinced me I should avoid them like the plague:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;They are handled differently which &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ms973837.aspx#dotnetgcbasics_topic5&quot;&gt;degrades performance&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;When they are called is non-deterministic&lt;/li&gt;
  &lt;li&gt;Any managed references may already be garbage collected and be horribly broken&lt;/li&gt;
  &lt;li&gt;Are only for cleaning up unmanaged resources&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;dont-do-it&quot;&gt;Don’t Do It&lt;/h1&gt;

&lt;p&gt;Odds are you will never need a Finalizer. If you are not sure then you shouldn’t
add one.&lt;/p&gt;

&lt;p&gt;We were using it for automatic clean up with only managed code. This
was both lazy and wrong. Instead, we should have used &lt;code class=&quot;highlighter-rouge&quot;&gt;IDisposable&lt;/code&gt; to
clean up at the end of the test.&lt;/p&gt;

&lt;p&gt;We learnt a valuable lesson: &lt;strong&gt;We didn’t need Finalizers&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;I would like to thank my co-workers, Daryl, Chris, &lt;a href=&quot;http://michaeljswart.com&quot;&gt;Michael Swart&lt;/a&gt; and Derek,
for digging into this issue with me. It was fun to find the eventual root cause,
fix this weird issue and learn more about Finalizers.&lt;/em&gt;&lt;/p&gt;

</content>
</entry>


<entry>
  <title type="html"><![CDATA[Are you your Code Reviews?]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/are-you-your-code-reviews/" />
  <id>http://www.smaclellan.com/posts/are-you-your-code-reviews</id>
  <published>2015-12-17T20:17:07-05:00</published>
  <updated>2015-12-17T20:17:07-05:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;I recently attended several fantastic developer talks where I &lt;a href=&quot;http://www.d2l.com/&quot;&gt;work&lt;/a&gt;.
My co-worker, Chris, had a very interesting talk sharing lessons he learnt during
7 months of code reviews with a remote team. He had some great
insights I have been thinking through. The one which sticks with me is: how your
code reviews are a reflection of you.&lt;/p&gt;

&lt;p&gt;Chris had the benefit of helping a remote team get started. It was really hard.
I appreciate the work his team put in. His presentation reviewed what he
learnt after months of working with the same people. Code reviews were the
focal point for most of his interactions.&lt;/p&gt;

&lt;p&gt;Things change when code reviews are the primary way you interact with someone.
You don’t know them as a person and
you cannot see them on a daily basis. If they keep giving crappy code reviews
your opinion of them forms quickly. Likewise, consistently great code can help
them stand apart.&lt;/p&gt;

&lt;p&gt;This was the reality for Chris while working with the remote team. Being a talk
on code reviews, he found special examples highlighting lessons learnt. He felt
after a while, the code reviews became the main representation of a person’s ability.&lt;/p&gt;

&lt;p&gt;This got me thinking about being evaluated and represented by each of my code
reviews. I thought about how I often become too attached to my code. It also
caused me to reflect on several great blog posts about separating your worth
from the code you write. These posts, in a nutshell, explain how ‘you are not
your code’. In the end, I think I found a way I can bring these differing ideas together.&lt;/p&gt;

&lt;div class=&quot;disclaimer&quot;&gt;
&lt;strong&gt;Reminder:&lt;/strong&gt; My blog is my own opinion and not necessarily that of my employer.
That said thanks for the great sessions!
&lt;/div&gt;

&lt;h1 id=&quot;invested&quot;&gt;Invested&lt;/h1&gt;

&lt;p&gt;Connecting with what Chris said, I take feedback to code reviews I make to
heart. On the receiving end reviewing code from others, I care about maintaining the quality of
what we built. When I send code reviews I try to be careful in how I approach
making changes. I hope I don’t look stupid.&lt;/p&gt;

&lt;p&gt;The dark side is when I treat comments I give or receive like an attack.
Reviews should be an open discussion and not used to showcase how brilliant you are.
Instead, humility and listening need to be applied to every code review.&lt;/p&gt;

&lt;p&gt;It is really easy to become invested in your code. I put lots of
effort and care into the work I do. I am emotionally invested. Too often
I behave defensively about my code and take feedback too personally.&lt;/p&gt;

&lt;p&gt;Feelings of ownership intensify the longer I have been on a project and what
role I had in its formation. We have been on our current project since it began
and seen it go through many changes. I care deeply about it and want to see it
succeed.&lt;/p&gt;

&lt;p&gt;Over the last few weeks, I wrapped up a project I worked on over the course of 7
months. At the same set of talks, I presented about how this project evolved.
I feel personally responsible for the code. It feels like any feedback on
the project or code reflects on me as a developer.&lt;/p&gt;

&lt;p&gt;I am self-conscious about by ability as a developer. I often feel like an
&lt;a href=&quot;http://www.hanselman.com/blog/ImAPhonyAreYou.aspx&quot;&gt;imposter&lt;/a&gt;. Combining those developer doubts with putting myself
out there in code reviews, you get a potent mix of feelings and lack of
confidence. My inner phony is on display.&lt;/p&gt;

&lt;h1 id=&quot;you-are-not-your-code&quot;&gt;You Are Not Your Code&lt;/h1&gt;

&lt;p&gt;There are many &lt;a href=&quot;http://sstephenson.us/posts/you-are-not-your-code&quot;&gt;great&lt;/a&gt; &lt;a href=&quot;http://www.hanselman.com/blog/YouAreNotYourCode.aspx&quot;&gt;blog&lt;/a&gt; &lt;a href=&quot;http://blog.codinghorror.com/egoless-programming-you-are-not-your-job/&quot;&gt;posts&lt;/a&gt; about how &lt;a href=&quot;https://www.google.ca/search?q=you+are+not+your+code&quot;&gt;you are not your code&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Each of these posts is a reminder to not be so serious. The code you write is
not your worth as a person. You are so much more. Don’t direct the suggestions
and criticism inward. Instead, use the constructive criticism for getting better.&lt;/p&gt;

&lt;p&gt;This is a message I need to take to heart. I need to separate myself from
suggestions for the code I have created.&lt;/p&gt;

&lt;p&gt;In preparing for my
presentation I had some great questions from others which forced me to re-evaluate
the decisions I thought were rock solid. Incorporating the extra feedback from
others made the finished product was even better.&lt;/p&gt;

&lt;p&gt;How does ‘you are not your code’ fit if your colleagues think about you based on
the code you share in code reviews? This seems like the opposite perspective.
Wrestling through this contradiction caused me to rethink Chris’ talk.&lt;/p&gt;

&lt;h1 id=&quot;caring-professionally&quot;&gt;Caring Professionally&lt;/h1&gt;

&lt;p&gt;I think both ideas can fit together. The sum total of your being is not
the code you write. How you present yourself, learn, care and interact with
others is a clear reflection of what you value. Code reviews are one avenue
for expressing yourself.&lt;/p&gt;

&lt;p&gt;In talking with Chris, he cares about the humans behind their code reviews. In
teasing apart what he said, I think caring about what you
do is the most important part of each code review. Not getting emotionally attached
to your code to the point where it consumes you. Care about your work and put
your best foot forward.&lt;/p&gt;

&lt;p&gt;If someone else is going to take the time to review your code be kind to them.
One recommendation from the talk was for you to thoroughly review your code
before sharing it. Go through the changes on your own and clean up any loose
ends. Add comments explaining the decisions you made. Show you care.&lt;/p&gt;

&lt;p&gt;I think constantly improving and trying your best is part of being a
professional programmer. Learn from your code reviews. Try to make the most
out of each review and the feedback you receive.&lt;/p&gt;

&lt;p&gt;Be supportive when interactive with others. Don’t stomp around and shoot down
their ideas. Treat others how you want to be treated and you cannot go wrong.&lt;/p&gt;

&lt;p&gt;Although I don’t count myself as a great developer, like &lt;a href=&quot;http://blog.codinghorror.com/egoless-programming-you-are-not-your-job/&quot;&gt;Jeff Atwood&lt;/a&gt;
I care too much.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Unfortunately, the world is full of people who don’t give a damn about their
work. Those of us who love programming enough to become highly skilled at it
tend to have the opposite problem – &lt;strong&gt;we care too much&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The solution is to convert caring into actions which help others.&lt;/p&gt;

&lt;p&gt;You are not your code, but your code reviews are a reflection of your workmanship.
Care about your work and do your best in every code review.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;P.S. Thanks Josh for helping me review this blog post. Without your help I
would be stuck in the present and past tense at the same time.&lt;/em&gt;&lt;/p&gt;

</content>
</entry>


<entry>
  <title type="html"><![CDATA[Don't Use A Singleton]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/dont-use-a-singleton/" />
  <id>http://www.smaclellan.com/posts/dont-use-a-singleton</id>
  <published>2015-12-06T19:12:07-05:00</published>
  <updated>2015-12-06T19:12:07-05:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;Singleton objects are not normally what you want to use to solve problems. It is great for
optimizing creating objects but otherwise has limited utility. Recently, I
had a change where I briefly considered using a Singleton to deal with it.
Using a Singleton to solve my problem would have been wrong and led to more
problems.&lt;/p&gt;

&lt;p&gt;I was refactoring some code which had some unusual data access. Each user used
a key/value store to save data and then later retrieve it. The data being saved
was pretty simple and the code treated the key/value as a really fancy cache.&lt;/p&gt;

&lt;p&gt;We decided to use the same key/value store for all users. Based on the data it
made sense for every user to see the same values. Sharing between users would
make the cache more effective.&lt;/p&gt;

&lt;p&gt;I thought I could take a shortcut. Since the values would be identical for all
users then why not use a Singleton object to store the value in memory. Every time
the class was used we could return the same object and store the necessary value
in a field. We could remove the key/value store completely and simplify the code.
Or so I thought.&lt;/p&gt;

&lt;p&gt;In the amazing image below, you can see what the code would look like before and
after using a Singleton to refactor the code.&lt;/p&gt;

&lt;figure class=&quot;image-center&quot;&gt;
	&lt;img title=&quot;Before everyone works alone, after it is a party!&quot; alt=&quot;A comparison of before and after. Before shows 3 people with their own key/value stores. After has the same 3 people all using the Singleton.&quot; src=&quot;http://www.smaclellan.com/images/singletons-before-after.JPG&quot; /&gt;
&lt;/figure&gt;

&lt;div class=&quot;disclaimer&quot;&gt;
This isn't the complete Singleton Pattern. My use case would have reused the same
object for the entire application without needing to restructure how the class was
accessed. I have included links discussing the full Singleton Pattern at the end
of this post. They come to the same conclusion.
&lt;/div&gt;

&lt;h1 id=&quot;intervention&quot;&gt;Intervention&lt;/h1&gt;

&lt;p&gt;But Scott you say, what about other servers! Other servers
would need the Singleton too! Umm, Scott … they would have different objects.
Oh right.&lt;/p&gt;

&lt;p&gt;The Singleton object starts to have issues immediately coordinating the same value
between multiple servers. There are a bunch of problems like:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Different servers would have different objects&lt;/li&gt;
  &lt;li&gt;Access to the data needs to be coordinated across threads&lt;/li&gt;
  &lt;li&gt;Restarting the application loses the saved values&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thankfully my co-worker, Daryl, reminded me of the issues a Singleton would
cause. Instead, we decided to store the value in the application’s database.
It also meant we could stop worrying about cache invalidation and simplify the
code since the database would always have the right value. Great. Problem solved.&lt;/p&gt;

&lt;p&gt;Using a Singleton to make this change is wrong. It would introduce other
issues which could be trivially avoided using other solutions.&lt;/p&gt;

&lt;h1 id=&quot;the-bigger-picture&quot;&gt;The Bigger Picture&lt;/h1&gt;

&lt;p&gt;After this brief lapse of sanity, we talked a little more about why Singletons
don’t make sense in your architecture. By definition, Singletons are a single
point of failure and cannot be scaled out. For any system with enough load
you want neither of those.&lt;/p&gt;

&lt;p&gt;Some Singletons in your architecture are HARD to avoid, like a centralized
database you use everywhere. Do whatever you can to make it redundant and
continue to scale as your application grows. Such Singletons may just be part
of doing business and once baked into the architecture are not worth the cost
to replace.&lt;/p&gt;

&lt;p&gt;You may have operations which should only run in one place. Not a problem,
use a semaphore (or &lt;a href=&quot;https://en.wikipedia.org/wiki/Leader_election&quot;&gt;leader election&lt;/a&gt; like the cool kids) to coordinate
who runs the operation then only run it in one place. Whatever runs the
operation can be scaled, redundant and perform many other useful operations.&lt;/p&gt;

&lt;p&gt;A better question is why do you have this operation/service which can only be
run in one place? If the code is important enough and needs more throughput you
may need to deal with your Singleton. Do what you can to allow it to run in
multiple places at the same time. If that fails, shrink the code which needs to
be exclusive as much as possible to avoid contention. Again consider making who
and where it runs more flexible.&lt;/p&gt;

&lt;h1 id=&quot;an-optimization&quot;&gt;An Optimization&lt;/h1&gt;

&lt;p&gt;So when does a Singleton object make sense? To avoid allocating many small objects or
very expensive objects.&lt;/p&gt;

&lt;p&gt;Both these cases are optimizations to existing code based
on specific circumstances. Prior to using a Singleton, you should investigate the
problem completely and determine all options you have available.&lt;/p&gt;

&lt;p&gt;Using a Singleton like this should be a specific micro-optimization which is
transparent to the rest of the application. In our applications, we have some
classes which are created once then injected into any class which needs them.
The consuming classes have no idea that they are all using the same object.
This works great for functional classes without any state or which talk directly
to our centralized database.&lt;/p&gt;

&lt;p&gt;Depending on how your component is
used you need to consider concurrency. The CPU/memory gains from reusing the
same object may be completely lost due to synchronization overhead.&lt;/p&gt;

&lt;h1 id=&quot;not-the-tool-for-the-job&quot;&gt;Not the Tool for the Job&lt;/h1&gt;

&lt;p&gt;In the end, a Singleton object was not the right tool for the job. In
thinking about it further, it is probably not the right tool for many jobs.
We were able to easily refactor the code using other techniques.&lt;/p&gt;

&lt;p&gt;My example wasn’t even using the complete Singleton Pattern and it was still bad!
For more reading on why Singletons are the worst:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons&quot;&gt;What is so bad about singletons?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://sites.google.com/site/steveyegge2/singleton-considered-stupid&quot;&gt;Singleton Considered Stupid&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx&quot;&gt;Why Singletons are Evil&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To recap: &lt;strong&gt;Singletons are bad, stupid and evil&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you think a Singleton is a perfect solution to your problem, double check.
There is probably different solution which fits better.&lt;/p&gt;

</content>
</entry>


<entry>
  <title type="html"><![CDATA[My Time As An Exterminator]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/exterminator/" />
  <id>http://www.smaclellan.com/posts/exterminator</id>
  <published>2015-11-30T18:37:07-05:00</published>
  <updated>2015-11-30T18:37:07-05:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;This week I am presenting to a large number of coworkers about work I started
as an &lt;a href=&quot;#&quot;&gt;Exterminator&lt;/a&gt;. For those which want to learn more about that time I
wanted to summarize all of the posts I had done.&lt;/p&gt;

&lt;p&gt;Earlier this year I went on a 4-month rotation to a different team. It a great
opportunity I learnt a great deal from doing. While on rotation I tried to
regularly blog what I was doing and what I was learning from it. Here is a
summary of all those posts.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href=&quot;/posts/i-volunteer-as-tribute/&quot;&gt;I volunteer as tribute&lt;/a&gt;&lt;/em&gt;. This was my first
post. I was really excited to join the Exterminator team. Learning new
things and helping people.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href=&quot;/posts/exterminators-1-the-4-stages-of-legacy-code/&quot;&gt;The 4 Stages of Legacy Code&lt;/a&gt;&lt;/em&gt;.
I had dived straight in and was having fun digging into code without tests.
I was accustomed to thorough test suites and working on brand new code. In the
end I was able to get through it and find good ways to approach this new
challenge.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href=&quot;/posts/exterminators-2-focus-and-quality/&quot;&gt;Focus and Quality&lt;/a&gt;&lt;/em&gt;. In order to keep myself honest, I
blogged about my goals for the year and how I intended to approach them.
This post and my goals, focus and quality, were a great way to ensure I was
concentrating on the right things while I was an Exterminator. The links included with
this post are fantastic and with the year end approaching it is time for me
to read them again.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href=&quot;/posts/exterminator-3-on-comments/&quot;&gt;On Comments&lt;/a&gt;&lt;/em&gt;. We talked about what makes
for good comments in code. Which comments are not necessary or too verbose. I
highlight a few cases where I think comments really add to the code. There is also some
amazing C code with silly comments.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href=&quot;/posts/exterminator-4-damp-unfiltered-aaa-tests/&quot;&gt;DAMP Unfiltered AAA&lt;/a&gt;&lt;/em&gt;. With
my added focus on quality, I spent lots of time writing tests. I delve into how
trying to not repeat yourself and stay DRY makes tests much harder to
understand. Instead, you want descriptive and meaningful phrases (DAMP) so
yours tests are clear.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href=&quot;/posts/exterminator-5-pull-request-explosion/&quot;&gt;Pull Requests&lt;/a&gt;&lt;/em&gt;. I tried
dabbling with breaking up a larger chunk of work into small pull requests.
This led to a pull request explosion! Everything became a small pull request
layered upon other pull requests. This fun exercise set the tone for the rest of
my time as an Exterminator.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href=&quot;/posts/exterminator-6-code-reviews/&quot;&gt;Code Reviews&lt;/a&gt;&lt;/em&gt;. I share my approach to
code reviews. I strive to learn/share ideas and understand the underlying logic
being updated. Hopefully, this approach leads to better conversations about the
code change.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href=&quot;/posts/exterminators-7-action-retros/&quot;&gt;Discuss into Action&lt;/a&gt;&lt;/em&gt;. We had a
retrospective which did not sit well with me. It was a good conversation but
did not lead to any action items. I was left wanting more.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href=&quot;/posts/exterminator-9-wrong-time-to-refactor/&quot;&gt;The Wrong Time to Refactor&lt;/a&gt;&lt;/em&gt;.
I like refactoring A LOT. You might even say too much. We were the day before
a release and fixing a late bug. I wanted to refactor the code more. We
decided as a team this was not the right thing to do. Later, we were able to
safely complete the refactoring.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href=&quot;/posts/exterminator-10-caught-by-conventions/&quot;&gt;Caught By Conventions&lt;/a&gt;&lt;/em&gt;. Oops.
I learnt a lesson by swimming upstream. I was excited to try a new tool,
&lt;a href=&quot;http://www.specflow.org/&quot;&gt;Specflow&lt;/a&gt;, and started by contributing code to another project. I
missed the memo and broke all the conventions within their project. It was very
frustrating and then I realized I had done this to myself. I was able to learn
from my bad pull request and teach others the lessons I encountered.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href=&quot;/posts/exterminator-11-my-nemesis-email/&quot;&gt;My Nemesis, Email&lt;/a&gt;&lt;/em&gt;. I was
very distracted this week. I go over some techniques for reducing your
interruptions, particularly from email.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href=&quot;/posts/exterminator-12-finding-the-bottleneck/&quot;&gt;Finding the Bottleneck&lt;/a&gt;&lt;/em&gt;.
This is a basic introduction to some of the performance testing tools in
Visual Studio. We were able to find hot spots in our code and apply
improvements. I then break down the process, highlight some of our biases
and lessons for next time. Go deeper.&lt;/p&gt;

&lt;p&gt;I hope enjoyed these posts from my time as an Exterminator.&lt;/p&gt;

</content>
</entry>


<entry>
  <title type="html"><![CDATA[Crafting Code with C#]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/crafting-code-with-csharp/" />
  <id>http://www.smaclellan.com/posts/crafting-code-with-csharp</id>
  <published>2015-11-22T18:42:07-05:00</published>
  <updated>2015-11-22T18:42:07-05:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;In this post. I am going to go show how to use the keywords in C# to restrict
your code and help you intentionally craft your APIs. While you can apply the
same ideas to external APIs, I will focus on backend C# code here. The following
examples are inspired by our code to highlight different techniques we use
to achieve the exact code behaviour and visibility we want.&lt;/p&gt;

&lt;h1 id=&quot;a-simple-example-a-factory&quot;&gt;A simple example: A Factory&lt;/h1&gt;

&lt;p&gt;Let’s try a simple example. If you have a factory class the class being created
can be made internal instead of public. Here is what you do NOT want to do:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;WidgetFactory&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;IWidget&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CoolWidget&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CoolWidget&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IWidget&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If &lt;code class=&quot;highlighter-rouge&quot;&gt;CoolWidget&lt;/code&gt; is public then why would you need the factory? People could
start calling the class directly which would make the factory unnecessary. With
other classes directly using &lt;code class=&quot;highlighter-rouge&quot;&gt;CoolWidget&lt;/code&gt; changing the constructor, dependencies
or creating a different class in the factory are all breaking changes.&lt;/p&gt;

&lt;p&gt;Instead, &lt;code class=&quot;highlighter-rouge&quot;&gt;CoolWidget&lt;/code&gt; should be internal! Much better. The factory cannot be
bypassed.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CoolWidget&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IWidget&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;hide-internals-a-worker-class&quot;&gt;Hide Internals: A Worker Class&lt;/h1&gt;

&lt;p&gt;Doing work in classes can get complicated. I looked through a whole bunch of
our code and found we often use private methods for doing little bits of work.&lt;/p&gt;

&lt;p&gt;We have worker classes for processing queued work which then send callbacks
indicating the work is done or has failed. Within the class, there was a handy
method for sending callbacks. The helper method would format the callback URL
and other parameters then use other classes to actually send the callback.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Worker&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WorkItem&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;work&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;SendCallback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;work&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CallbackUrl&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SendCallback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Uri&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The sample above shares too much. Why would &lt;code class=&quot;highlighter-rouge&quot;&gt;SendCallback&lt;/code&gt; be public? It
doesn’t fit with &lt;code class=&quot;highlighter-rouge&quot;&gt;Worker&lt;/code&gt;’s purpose: processing work items. The method is
only used by &lt;code class=&quot;highlighter-rouge&quot;&gt;Worker&lt;/code&gt; and is nicely isolated to the class. Since
we would never want other classes using the method, it should be private!&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Worker&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SendCallback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Uri&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Much better. Had we left this method public it could accidentally be used.
Keeping it private allows it to continue to evolve separately from the API of
&lt;code class=&quot;highlighter-rouge&quot;&gt;Worker&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Sounds good, right? There is a catch, testing these methods is harder. You can’t
test them as easily because they are now private. Instead, you need to test them
indirectly through the inputs/outputs of other methods or using their behaviours.
If the logic is really complicated you might want to move it into separate
classes and interfaces.&lt;/p&gt;

&lt;p&gt;In the example above we have separated sending the callback into a
different class. This lets us test the &lt;code class=&quot;highlighter-rouge&quot;&gt;Worker&lt;/code&gt; and sending callbacks separately.
The logic for sending callbacks is consolidated in the dedicated class.
The private method in &lt;code class=&quot;highlighter-rouge&quot;&gt;Worker&lt;/code&gt; is still useful
and allows us to prepare the &lt;code class=&quot;highlighter-rouge&quot;&gt;Payload&lt;/code&gt; to be sent. The resulting helper classes look
like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ISender&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SendCallback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Uri&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Payload&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Sender&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SendCallback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Uri&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Payload&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This lets us keep the logic testable and the external API small. There
are now more classes which might make the code more complicated.&lt;/p&gt;

&lt;p&gt;We intentionally keep these helper classes internal. While they are useful on their own,
they have been created for use only within this assembly. Right now we don’t think
anyone else would want to send their callbacks the same way. Due to this we have
left them out of the public API until we are proven otherwise.&lt;/p&gt;

&lt;h1 id=&quot;inheritance-family-planning&quot;&gt;Inheritance: Family Planning&lt;/h1&gt;

&lt;p&gt;Controlling inheritance is useful. Most developers I work with avoid using it
like the plague due to issues they had in the past. &lt;a href=&quot;https://en.wikipedia.org/wiki/Composition_over_inheritance&quot;&gt;Composition over inheritance&lt;/a&gt;
is not only recommended, it is enforced by marking most classes as &lt;code class=&quot;highlighter-rouge&quot;&gt;sealed&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CantTouchThis&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Marking classes as &lt;code class=&quot;highlighter-rouge&quot;&gt;sealed&lt;/code&gt; prevent the class from being inherited. This
stops inheritance abuse. To be honest, I think it is overkill since there
are very few cases where you need to explicitly block inheritance. More often
than not you don’t have to worry about it. People don’t willy nilly start
inheriting from classes when none of the methods can be overridden and there
are no protected fields.&lt;/p&gt;

&lt;h1 id=&quot;inheritance-template-class&quot;&gt;Inheritance: Template Class&lt;/h1&gt;

&lt;p&gt;I think base classes can be useful when used correctly. I use them to setup &lt;a href=&quot;https://sourcemaking.com/design_patterns/template_method&quot;&gt;template methods&lt;/a&gt;
or share common/optional functionality. This isn’t a technique I use too often.
I like to treat it as yet another code design tool.&lt;/p&gt;

&lt;p&gt;To enforce the purpose you envisioned for your base classes, I recommend using
&lt;code class=&quot;highlighter-rouge&quot;&gt;abstract&lt;/code&gt; classes and methods. This keyword ensures your desired methods must be
implemented by child classes. The base class itself cannot be instantiated
which further clarifies its purpose as a base class.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TaxesCalculatorBase&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;decimal&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CalculateTaxes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;decimal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;multiplier&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetTaxesMultiplier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;totalIncome&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;decimal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetTaxesMultiplier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;decimal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;totalIncome&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FlatTaxesCalculator&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TaxesCalculatorBase&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetTaxesMultiplier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;decimal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;totalIncome&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0.05&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ProgressiveTaxesCalculator&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TaxesCalculatorBase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetTaxesMultiplier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;decimal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;totalIncome&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;totalIncome&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;75000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0.15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;totalIncome&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;50000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0.12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;totalIncome&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;25000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0.08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0.05&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;TaxesCalculatorBase&lt;/code&gt; is an abstract class with the template method
&lt;code class=&quot;highlighter-rouge&quot;&gt;CalculateTaxes&lt;/code&gt; which uses the abstract &lt;code class=&quot;highlighter-rouge&quot;&gt;GetTaxesMultiplier&lt;/code&gt; method.
Classes inheriting from &lt;code class=&quot;highlighter-rouge&quot;&gt;TaxesCalculatorBase&lt;/code&gt; must implement
the required methods and can do so however they like. To prevent the hierarchy from
growing out of hand, you can optionally mark the child classes as &lt;code class=&quot;highlighter-rouge&quot;&gt;sealed&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Another usage of base classes is implementing common or optional functions. I used
this recently to make optionally implementing part of an API easier. The class
had a method to return an &lt;code class=&quot;highlighter-rouge&quot;&gt;IEnumerable&lt;/code&gt;. The default implementation in the
base class returns an empty list. When the team was ready we could update the
child classes one at a time to provide the new functionality.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ExampleProviderBase&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IExample&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetExamples&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Enumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IExample&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;all-action-helper-classes&quot;&gt;All Action: Helper Classes&lt;/h1&gt;

&lt;p&gt;Every now and then we have helper classes with only methods and no state.
Stateless classes can be made &lt;code class=&quot;highlighter-rouge&quot;&gt;static&lt;/code&gt; to prevent them
from being instantiated or having instance variables added. If you had a
helper classes for &lt;code class=&quot;highlighter-rouge&quot;&gt;Uri&lt;/code&gt;’s it might look like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UrlHelpers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Uri&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FormatUri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Uri&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baseUrl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;route&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Uri&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TruncateUri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Uri&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baseUrl&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Uri&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SomethingCoolWithAUri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Uri&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baseUrl&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;static&lt;/code&gt; constraint helps the class stay stateless and cannot be instantiated. Having the class be
&lt;code class=&quot;highlighter-rouge&quot;&gt;static&lt;/code&gt; ensures all the methods must also be declared as &lt;code class=&quot;highlighter-rouge&quot;&gt;static&lt;/code&gt;.&lt;/p&gt;

&lt;h1 id=&quot;manage-state-immutable-classes&quot;&gt;Manage state: Immutable Classes&lt;/h1&gt;

&lt;p&gt;I think it is worth the minor effort to control whether fields/properties can
be modified. Limiting the number of ways data can be modified and passed around
can help highlight the right way to use your classes. The extreme version of
this are immutable classes which cannot have their values changed and must be
fully initialized when they are created.&lt;/p&gt;

&lt;p&gt;In this simple example, I have made a &lt;code class=&quot;highlighter-rouge&quot;&gt;Person&lt;/code&gt; class which is immutable. There
would be other classes for retrieving and updating the data. Anyone trying to
create a &lt;code class=&quot;highlighter-rouge&quot;&gt;Person&lt;/code&gt; must provide the necessary value at creation time. This is
a great opportunity to validate any inputs to prevent invalid objects from being
created.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FirstName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LastName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;FirstName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;LastName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can take this even further if you would like. I used properties to make
writing &lt;code class=&quot;highlighter-rouge&quot;&gt;FirstName&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;LastName&lt;/code&gt; easier. You can just as easily use
&lt;code class=&quot;highlighter-rouge&quot;&gt;readonly&lt;/code&gt; to force the fields to be initialized inside the constructor.
This allows the compiler to enforce keeping the class immutable.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_firstName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_lastName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FirstName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_firstName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LastName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_lastName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;m_firstName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;m_lastName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In &lt;a href=&quot;https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6&quot;&gt;C# 6&lt;/a&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;readonly&lt;/code&gt; fields become even easier thanks to getter only properties.
This is the same as the first example except for the missing &lt;code class=&quot;highlighter-rouge&quot;&gt;private set&lt;/code&gt; on the
properties. Like the second example, the compiler will again ensure the properites are
not modified outside the constructor.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FirstName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LastName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;FirstName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;LastName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Another great immutability technique is to create a new object with every
operation which would otherwise modify the current object. Great examples of this
approach are the &lt;code class=&quot;highlighter-rouge&quot;&gt;DateTime&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;string&lt;/code&gt; classes:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;n&quot;&gt;DateTime&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;now&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DateTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DateTime&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;future&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddDays&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2.5&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;now&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;future&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;The future {0} is different than now {1}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;future&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;now&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;example&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello World&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;updated&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;l&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;updated&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Heo Word&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;The example phrase was updated!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Immutable classes strongly affect how users interact with them. They can
reinforce readonly parts your API and highlight how you want data to be updated.&lt;/p&gt;

&lt;h1 id=&quot;generics-a-different-animal&quot;&gt;Generics: A Different Animal&lt;/h1&gt;

&lt;p&gt;Generics are an extremely powerful way to stay flexible while remaining strongly typed.
Adding constraints to generic parameters, ensure the types used with your class
match your expectations. If nothing else I find the constraints are a
&lt;a href=&quot;#generics-fun&quot;&gt;fun&lt;/a&gt; way to strictly enforce strong typing.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// T is both an Exception and has a default constructor&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ExceptionThrower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Using generics to keep callers type safe&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Cloner&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;For&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;original&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ICloneable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;original&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Clone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Fun with generics to create type safe factories&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DefaultFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;I hope you enjoyed these examples showcasing the C# keywords and how you can
use them to create the exact API you want. I believe it is important to
intentionally limit the surface area of your API by restricting how your
classes can be used and the properties/methods they expose. Carefully crafting
your API should make future maintenance easier.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong id=&quot;generics-fun&quot;&gt;Fun with Generics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I decided to move this to the footer. I have been known to abuse generics
in the past. Here is some fun code which has constraints against
multiple types. This ensures stronger types throughout the API. Within the class, less
restrictive types are used to avoid needing a common interface for the inputs.&lt;/p&gt;

&lt;p&gt;I would discourage using this particular class in your code. Use a DI container
like &lt;a href=&quot;http://autofac.org/&quot;&gt;Autofac&lt;/a&gt; instead.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FactoryCollection&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dictionary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_factories&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dictionary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TFactoryType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TFactoryType&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TFactoryType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;m_factories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TFactoryType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TFactoryType&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TFactoryType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TFactoryType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TFactoryType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DefaultFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&amp;gt;(&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DefaultFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;()&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TryCreate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;nc&quot;&gt;Type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m_factories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ContainsKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;IFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TDependencyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m_factories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</content>
</entry>


<entry>
  <title type="html"><![CDATA[Do what must be done]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/do-what-must-be-done/" />
  <id>http://www.smaclellan.com/posts/do-what-must-be-done</id>
  <published>2015-11-09T18:16:07-05:00</published>
  <updated>2015-11-09T18:16:07-05:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;This is going to be an interesting week. Deadlines are tight. Life doesn’t
stop and has more than its fair share of fun. Instead of bemoaning our lot I
have decided to do something about it. Work needs to get done and so we can
step up. We will do what must be done.&lt;/p&gt;

&lt;p&gt;We have a whole bunch of things stacked against us this week. There have been
some surprises. People we depend on are not available. New projects are
appearing and demanding our attention. It will be a challenge.&lt;/p&gt;

&lt;p&gt;To add insult to injury we are dealing with some adversity at home, which will
affect us for the coming year. I will need to miss work because of it. This
will not be an easy thing to get past and we are very thankful for our
incredibly supportive friends and family.&lt;/p&gt;

&lt;p&gt;I am excited to meet our problems head on. Not only do I think we will get all
the projects done, I think we will excel if we put our minds to it. I think
there are a few things I can do to help make this week a success.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be positive.&lt;/strong&gt; It would be easier to curl up into a ball and try to ignore
what is happening. Although the circumstances are disheartening there is hope.
We need to remain positive and strive for the best. If we focus on the negative
it will make everything else worse.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be patient.&lt;/strong&gt; Not everything is going to be magical. We will need to deal
with more fun as it rolls in. Instead of being overwhelmed by the changes we
need to patiently deal with them. The situation might not be ideal, but we
can get through it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be proactive.&lt;/strong&gt; Don’t sit back and let the challenges come to you. Embrace
and overcome them. I plan on doing what I can to help out and get things done.
To step up where I am needed most. My normal work might suffer, but we will
get through our deadlines.&lt;/p&gt;

&lt;p&gt;Although it will be hard I am optimistic about this week. If we remain positive,
stay patient and are proactive we will get through it. This week I have decided
to step up and do what must be done.&lt;/p&gt;
</content>
</entry>


<entry>
  <title type="html"><![CDATA[Dependency Injection Fun in NancyFx/TinyIoC]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/di-container-fun/" />
  <id>http://www.smaclellan.com/posts/di-container-fun</id>
  <published>2015-11-05T19:34:07-05:00</published>
  <updated>2015-11-05T19:34:07-05:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;This week my coworkers, Chris and Viktor, had a fun issue where it was hard to
find the root cause. They added some caching to speed up a heavily used
API which led to some tests breaking unexpectedly. In this post I wanted to dig
into the root cause behind why the tests broke.&lt;/p&gt;

&lt;p&gt;The one major lesson I learnt last year was the importance of
&lt;a href=&quot;/posts/lessons-learnt-while-finding-the-root-cause/&quot;&gt;getting to the root cause for unknown behaviour&lt;/a&gt;. My coworkers were doing
a focused performance improvement. On the surface the change was straight
forward. They wanted to add caching to a specific request which queried the
same values multiple times.&lt;/p&gt;

&lt;p&gt;To simplify the logic they decided to reuse the same values ever time it was
used during a request. This kept the caching rules really simple and meant
we did not have to care about cache invalidation. A new request could get new values and
we did not need to determine how long cached values are valid.&lt;/p&gt;

&lt;p&gt;The solution
was to create a class per request which would read the underlying value once
then save it to a field. To get the underlying value we delegate to the
real provider. Every future query for the value would return the
saved value from the field. The code for this new caching looks like:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CachingProvider&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IProvider&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_inner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CachingProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inner&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;m_inner&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;m_value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_inner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We adjusted our dependency injection configuration to create one
&lt;code class=&quot;highlighter-rouge&quot;&gt;CachingProvider&lt;/code&gt; per request. For this application we are using
&lt;a href=&quot;http://nancyfx.org/&quot;&gt;NancyFX&lt;/a&gt; with the built in &lt;a href=&quot;https://github.com/grumpydev/TinyIoC&quot;&gt;TinyIoC&lt;/a&gt; dependency injection
container. To perform the change we updated our NancyBootstrapper configuration
so TinyIoc would reuse the same &lt;code class=&quot;highlighter-rouge&quot;&gt;CachingProvider&lt;/code&gt; for each request.
Then we were off to the races!&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NancyBootstrapper&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DefaultNancyBootstrapper&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConfigureRequestContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;TinyIoCContainer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;NancyContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Register other types here&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;IProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;implementation&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Resolve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RealProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CachingProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;implementation&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;trouble-in-paradise&quot;&gt;Trouble In Paradise&lt;/h1&gt;

&lt;p&gt;The code cached the new values fantastically. The bad pages were now much better.
However, the change broke an integration tests which seemed unrelated.&lt;/p&gt;

&lt;p&gt;The broken test was a large integration test which faked a bunch of tricky
dependencies. These special dependencies needed to be updated so we could
control the test behaviour.&lt;/p&gt;

&lt;p&gt;With some more investigation we found out &lt;code class=&quot;highlighter-rouge&quot;&gt;IProvider&lt;/code&gt; was one of the types we
were faking out. We tracked down the test code which registered it’s
own implementation of &lt;code class=&quot;highlighter-rouge&quot;&gt;IProvider&lt;/code&gt; to overwrite the real type. This was again
done via the dependency injection container like so:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TestBootstrapper&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NancyBootstrapper&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConfigureApplicationContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;TinyIoCContainer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Register other types here&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TestProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Although we had found out what broke the test, we still had not fixed it or learnt why
it broke.&lt;/p&gt;

&lt;h1 id=&quot;getting-it-working&quot;&gt;Getting It Working&lt;/h1&gt;

&lt;p&gt;After many hours of debugging and head to desk slamming Chris and Viktor managed
to fix the issue by changing how the registration was overridden. They
replaced how &lt;code class=&quot;highlighter-rouge&quot;&gt;IProvider&lt;/code&gt; was registered with a method which could be overridden.
This change was pretty invasive and also moved around how other types were registered (not shown here).&lt;/p&gt;

&lt;p&gt;In the normal bootstrapper they added a virtual method to register the updated type:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NancyBootstrapper&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DefaultNancyBootstrapper&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConfigureRequestContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;TinyIoCContainer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;NancyContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Register other dependencies&lt;/span&gt;

        &lt;span class=&quot;nf&quot;&gt;RegisterProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// The new method they added&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RegisterProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;TinyIoCContainer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;IProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;implementation&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Resolve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RealProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CachingProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;implementation&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then in the test bootstrapper they override the new method to register the
fake &lt;code class=&quot;highlighter-rouge&quot;&gt;IProvider&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TestBootstrapper&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NancyBootstrapper&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RegisterProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;TinyIoCContainer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TestProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This worked but they still had not gotten the root cause as to why the test
was broken. They had only addressed the symptom which was causing the test to fail.
It is not shown here, but several other methods were moved around to accommodate the change. We did not
like this and knew there must be a better way.&lt;/p&gt;

&lt;h1 id=&quot;going-deeper-the-root-cause&quot;&gt;Going Deeper: The Root Cause&lt;/h1&gt;

&lt;p&gt;If you look closely at the code samples above you can see the type switched
from being registered for the Application to registered for each Request. While
this seems fine it meant the tests would resolve the actual type instead of the
fake &lt;code class=&quot;highlighter-rouge&quot;&gt;IProvider&lt;/code&gt; they should be using.&lt;/p&gt;

&lt;p&gt;The per Request dependencies are registered with a separate
&lt;code class=&quot;highlighter-rouge&quot;&gt;TinyIoCContainer&lt;/code&gt; which is a child of the Application container. When the
types are resolved the Request container is tried first and if nothing is found
then the Application container is tried. If nothing is found the dependency
fails to resolve which can cause an exception.&lt;/p&gt;

&lt;figure class=&quot;image-center&quot;&gt;
	&lt;img src=&quot;/images/di-levels.jpg&quot; alt=&quot;An image of the Application and Request containers with the TestProvider and CachingProvider respectively beside them&quot; /&gt;
	&lt;figcaption&gt;
		The test failed because it found the new CachingProvider instead of the TestProvider it needed.
	&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;With this new knowledge the fix was relatively straight forward. We registered
the fake &lt;code class=&quot;highlighter-rouge&quot;&gt;IProvider&lt;/code&gt; per Request. This overwrites the &lt;code class=&quot;highlighter-rouge&quot;&gt;CachingProvider&lt;/code&gt;
registration with the &lt;code class=&quot;highlighter-rouge&quot;&gt;TestProvider&lt;/code&gt; and solves the problem.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Fixed Test Boot&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TestBootstrapper&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NancyBootstrapper&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConfigureApplicationContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;TinyIoCContainer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Register other types here&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Previously configured here&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// container.Register&amp;lt;IProvider, TestProvider&amp;gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConfigureRequestContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;TinyIoCContainer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;NancyContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Register other types here&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Fixes the root cause&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TestProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;public-service-announcement&quot;&gt;Public Service Announcement&lt;/h1&gt;

&lt;p&gt;Phew. You made it this far. What is the major lesson?&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;It is important to &lt;a href=&quot;/posts/lessons-learnt-while-finding-the-root-cause/&quot;&gt;understand how your code works&lt;/a&gt;!
Especially when it doesn’t.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We went deeper into Nancy and figured out how the dependency injection worked!
It was great. Afterwards, we could make the fix in a much simpler way.&lt;/p&gt;

&lt;p&gt;Next time you are troubleshooting an issue make sure you find the root cause.
Going deeper is worth the extra time. You will understand the problem better
and the next time something comes up you will know what to do.&lt;/p&gt;

&lt;p&gt;Until then happy troubleshooting.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;I would like to thank Chris and Viktor for letting me write up this post and
doing all the leg work for this issue.&lt;/em&gt;&lt;/p&gt;

</content>
</entry>


<entry>
  <title type="html"><![CDATA[Basic PowerShell Remoting]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/basic-powershell-remoting/" />
  <id>http://www.smaclellan.com/posts/basic-powershell-remoting</id>
  <published>2015-11-01T18:45:07-05:00</published>
  <updated>2015-11-01T18:45:07-05:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;Using remote PowerShell commands is a great way to manage servers.
I have been spending more time using Windows 2012 Server Core which makes using
remote tools essential. Instead of connecting using Remote Desktop, I try to do
everything using PowerShell remotely. In this post, I will show off some
extremely basic remote PowerShell commands, &lt;code class=&quot;highlighter-rouge&quot;&gt;Enter-PSSession&lt;/code&gt; and
&lt;code class=&quot;highlighter-rouge&quot;&gt;Invoke-Command&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let’s start with a simple command:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-powershell&quot; data-lang=&quot;powershell&quot;&gt;Enter-PSSession -ComputerName &lt;span class=&quot;s1&quot;&gt;'Target'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This amazing command uses your current PowerShell prompt to run PowerShell
commands interactively on the remote computer, “Target”. When you
are done type &lt;code class=&quot;highlighter-rouge&quot;&gt;exit&lt;/code&gt;. With this command you now have the complete
might of a fully operational PowerShell!&lt;/p&gt;

&lt;figure class=&quot;image-center&quot;&gt;
	&lt;a href=&quot;https://commons.wikimedia.org/wiki/File%3ALong_Beach_Comic_Expo_2011_-_Darth_Vader_and_his_stormtroopers_(5648076179).jpg&quot;&gt;
		&lt;img width=&quot;480&quot; alt=&quot;Long Beach Comic Expo 2011 - Darth Vader and his stormtroopers (5648076179)&quot; src=&quot;https://upload.wikimedia.org/wikipedia/commons/thumb/c/c8/Long_Beach_Comic_Expo_2011_-_Darth_Vader_and_his_stormtroopers_%285648076179%29.jpg/640px-Long_Beach_Comic_Expo_2011_-_Darth_Vader_and_his_stormtroopers_%285648076179%29.jpg&quot; /&gt;
	&lt;/a&gt;
	&lt;figcaption&gt;
		By &lt;a href=&quot;http://www.flickr.com/people/26728047@N05&quot;&gt;The Conmunity - Pop Culture Geek&lt;/a&gt; from Los Angeles, CA, USA &lt;a rel=&quot;nofollow&quot; href=&quot;http://creativecommons.org/licenses/by/2.0&quot;&gt;CC BY 2.0&lt;/a&gt;, via Wikimedia Commons
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;!-- https://www.flickr.com/photos/elaws/3775252224 --&gt;

&lt;p&gt;You can run single or multiple commands using
&lt;code class=&quot;highlighter-rouge&quot;&gt;Invoke-Command&lt;/code&gt;. Unlike &lt;code class=&quot;highlighter-rouge&quot;&gt;Enter-PSSession&lt;/code&gt;, this command is not interactive
and will still stream results back to your current prompt. This is great for
one line commands like restarting IIS on the remote server “Target”:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-powershell&quot; data-lang=&quot;powershell&quot;&gt;Invoke-Command -ComputerName &lt;span class=&quot;s1&quot;&gt;'Target'&lt;/span&gt; -ScriptBlock &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; iisreset &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Remote commands are allowed by default on Windows Server 2012 and beyond.
On older operating systems you can run &lt;code class=&quot;highlighter-rouge&quot;&gt;Enabled-PSRemoting -Force&lt;/code&gt; from
an Administrator PowerShell prompt on the target machine to enable remoting. You can
then test the connection by running the following from another computer:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-powershell&quot; data-lang=&quot;powershell&quot;&gt;Invoke-Command -ComputerName &lt;span class=&quot;s1&quot;&gt;'Target'&lt;/span&gt; -ScriptBlock &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'hello'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;There are many other commands which natively support remote operations.
These commands will often have a &lt;code class=&quot;highlighter-rouge&quot;&gt;ComputerName&lt;/code&gt; parameter. You can see a list
of commands with the &lt;code class=&quot;highlighter-rouge&quot;&gt;ComputerName&lt;/code&gt; parameter by using:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-powershell&quot; data-lang=&quot;powershell&quot;&gt;Get-Command -ParameterName &lt;span class=&quot;s1&quot;&gt;'ComputerName'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Among my favourites is &lt;code class=&quot;highlighter-rouge&quot;&gt;Get-EventLog&lt;/code&gt;. It is a great way to look at messages
from a remote server without ever leaving the terminal. This example
retrieves, formats and displays the last 5 error messages from the remote
server “Target”:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-powershell&quot; data-lang=&quot;powershell&quot;&gt;&lt;span class=&quot;nb&quot;&gt;Get-EventLog&lt;/span&gt; -ComputerName &lt;span class=&quot;s1&quot;&gt;'Target'&lt;/span&gt; -LogName &lt;span class=&quot;s1&quot;&gt;'Application'&lt;/span&gt; -Newest 5 -EntryType &lt;span class=&quot;s1&quot;&gt;'Error'&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;`&lt;/span&gt;
	| &lt;span class=&quot;nb&quot;&gt;Format-List &lt;/span&gt;TimeWritten, Message &lt;span class=&quot;se&quot;&gt;`&lt;/span&gt;
	| more&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I hope you liked this mini intro to PowerShell remoting.
Now go run some commands!&lt;/p&gt;
</content>
</entry>


<entry>
  <title type="html"><![CDATA[Being Shippable At All Times]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/shippable-at-all-times/" />
  <id>http://www.smaclellan.com/posts/shippable-at-all-times</id>
  <published>2015-10-29T21:00:07-04:00</published>
  <updated>2015-10-29T21:00:07-04:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;In this post I explore two approaches to being shippable at all times;
knowing your Last Known Good package or having a Golden Master. Our team
thoroughly tracks our last good package we have built and tested. Other teams stay
shippable by keeping whatever is currently checked in stable. They can ship
their master branch and we can ship our Last Known Good package.&lt;/p&gt;

&lt;p&gt;In order to ship software you need to do the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Choose what to ship.&lt;/li&gt;
  &lt;li&gt;Produce code worth shipping.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your code is no good or always breaks the build then you will not have
anything to ship. You shouldn’t choose to ship garbage.&lt;/p&gt;

&lt;p&gt;By releasing something you implicitly choose what you want to ship. Often there
will be multiple builds/commits to choose from which could be shipped.&lt;/p&gt;

&lt;p&gt;With solid Continuous Integration you can improve the confidence in each commit.
The confidence from great unit and acceptance testing can be enough to declare
any build shippable.&lt;/p&gt;

&lt;p&gt;Lately, teams we work with have been intentionally trying to stay shippable.
They want to support releasing at any point and other Continuous Delivery
norms. Our team has long been trying to track the last package we deemed
shippable. Both approaches are effective and have their own trade-offs.&lt;/p&gt;

&lt;p&gt;We focus on choosing what to ship based on previous good builds. It means we can always ship something when
we want to release. We keep track of the last build to be fully
tested, what went into it and where it has been deployed. From this
we choose our Last Known Good version. When it comes time to release
into production we ship that version.&lt;/p&gt;

&lt;p&gt;The other teams focus on keeping their master branch shippable at all times. This
goes above and beyond keeping their Continuous Integration process green. No changes
can be merged which would prevent the code from releasing. Risky changes should be
broken down. When it is time to release the latest commit to the master branch is used.&lt;/p&gt;

&lt;h1 id=&quot;last-known-good&quot;&gt;Last Known Good&lt;/h1&gt;

&lt;figure class=&quot;image-center&quot;&gt;
	&lt;img src=&quot;/images/lkg.jpg&quot; alt=&quot;An image of various builds and commits highlighting the Last Known Good package&quot; /&gt;
	&lt;figcaption&gt;
		The Last Known Good package picked from the possible builds from the master branch.
	&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;We track our last known good set of binaries through our deployment pipeline
and then choose which one set we want to ship at the end of the release. We
know exactly what went into each build and the testing which was performed.&lt;/p&gt;

&lt;p&gt;With this approach there are few aspects which are really important:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Knowing what has been committed to each build&lt;/li&gt;
  &lt;li&gt;Tracking builds between different stages/validation&lt;/li&gt;
  &lt;li&gt;Visibility into the deployment pipeline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What we ship is choice by our team supported by tracking what is in each build. If more
testing and validation is required we communicate with the team to make sure it
happens before we release. We closely follow which stories are included
in each build.&lt;/p&gt;

&lt;p&gt;There is more communication overhead with this approach. The more people involved
with each releases the harder it is to agree on what the Last Known Good
is at any given point.&lt;/p&gt;

&lt;p&gt;The current branch does not need to be perfect. Doing testing on the master branch is okay,
but needs to be coordinated. The worst case is master may be broken for short
periods. This can be dangerous for less
rigorous teams who may leave their code broken for days. It is still highly
recommended to use Continuous Integration and keep builds green.&lt;/p&gt;

&lt;h1 id=&quot;golden-master&quot;&gt;Golden Master&lt;/h1&gt;

&lt;figure class=&quot;image-center&quot;&gt;
	&lt;img src=&quot;/images/golden-master.jpg&quot; alt=&quot;Multiple branches merged into a master branch. The tip is highlighted as the Golden Master&quot; /&gt;
	&lt;figcaption&gt;
		The Golden Master keeping the master branch shippable. Can always release the latest commit.
	&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Other teams focus on keeping their code shippable by ensuring the master branch
can always be built and deployed. For each commit, they ensure all integration tests
pass thanks to solid Continuous Integration. The majority of the deployment
pipeline is automated. More stability may be achieved using extra hardening phases.&lt;/p&gt;

&lt;p&gt;Key aspects ensure the code remains stable by:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Avoiding build break at all costs&lt;/li&gt;
  &lt;li&gt;Extensive &lt;a href=&quot;/posts/preflights-changed-our-world/&quot;&gt;preflights&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;More validation performed prior to merging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Changes requiring manual testing are problematic. They are inherently
not “always shippable” once they have been merged. Some teams compensate with even
more testing prior to merging to avoid breaking master. Others accept short
hardening periods to test all the code which has been committed.&lt;/p&gt;

&lt;p&gt;I have worries about this approach and am biased to the Last Known Good. It seems
to be running well for teams using it, but can lead to problems due to delayed
merges. Since the emphasis is on staying stable changes can be delayed or avoided.
Refactoring is harder if teams merge less frequently. Teams need to focus on
merging small changes frequently. Another great mitigation is to merge sooner and
keeping risky code behind feature flags for later testing. It is imperative to
avoid merging ALL THE CHANGES at the end of a release cycle.&lt;/p&gt;

&lt;p&gt;Choosing what to ship is easy. Use the latest commit. No need to get fancy
picking which build or tracking what has happened.&lt;/p&gt;

&lt;h1 id=&quot;risk&quot;&gt;Risk&lt;/h1&gt;

&lt;p&gt;All releases have risks. Whether the risks are technological or business-related it
does not matter. Every change includes some element of uncertainty. Both Last
Known Good and Golden Master strategies address the risks associated with
releases but approach the problem differently.&lt;/p&gt;

&lt;p&gt;The Last Known Good approach builds in accounting for risk in how you choose
which version to use. Picking which builds are good could be a factor of
automated testing, selection by testers, voting by a group of people, etc.
Business pressure to release something too soon can cause issues to be shipped
to production.&lt;/p&gt;

&lt;p&gt;Gaps in automation indicating whether or not master is broken reduce the
effectiveness of the Golden Master. As with any CI process, they are only as
good as the coverage they provide. Risk can be reduced with an extra
hardening period or intermediate branches, but this pushes the problem
to that location and introduces delays.&lt;/p&gt;

&lt;p&gt;Both approaches suffer from issues with the validation used to determine good
versions and stop bad versions. If the version choice or validation are incomplete
then bad versions will sneak through.&lt;/p&gt;

&lt;h1 id=&quot;next-step-going-continuous&quot;&gt;Next Step: Going Continuous&lt;/h1&gt;

&lt;p&gt;If you take both approaches to the limit you end up at Continuous Delivery and
Continuous Deployment. Shipping more frequently and being ready to release at
any moment.&lt;/p&gt;

&lt;p&gt;With Continuous Delivery it is important to be able to release at any point. What
and when to release is chosen based on needs and features. It is essential to
do comprehensive testing in development by deploying to production-like environments.
The deployment process and configuration should be automated. This is close to
our Last Known Good approach with a great emphasis on being deployment ready.
The Golden Master can easily be used the same way since every commit should be
shippable.&lt;/p&gt;

&lt;p&gt;Continuous Deployment takes Continuous Delivery further. Every build which
passes automated testing is automatically deployed into production.
It is what you would get if after you tested your Golden Master you deployed
every passing build into production.&lt;/p&gt;

&lt;p&gt;To know gauge how continuous your process is you can use this test from &lt;a href=&quot;http://martinfowler.com/bliki/ContinuousDelivery.html&quot;&gt;Martin Fowler&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The key test is that a business sponsor could request that
&lt;strong&gt;the current development version of the software can be deployed into production at a moment’s notice&lt;/strong&gt;&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;and nobody would bat an eyelid, let alone panic.&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Both our team and others are trying to do Continuous Delivery. We
make potential releases all the time and then choose when we want to ship based
on our client needs. Earlier this year we &lt;a href=&quot;/posts/deploys-becoming-boring-part-1/&quot;&gt;accelerated our releases&lt;/a&gt; and
do full Continuous Deployment into some environments. Releasing more often has
been fantastic and lets us react to changes more effectively.&lt;/p&gt;

&lt;p&gt;So far our focus in this blog post has been on everything leading up to a final
release into production. Improving your release process and
shipping continuously is the logical next step.&lt;/p&gt;

&lt;p&gt;Don’t stop at being shippable; keep going for Continuous Delivery or Continuous
Deployment.&lt;/p&gt;

&lt;p&gt;For a more thorough description of each term see this fantastic Stack Overflow
question: &lt;a href=&quot;http://stackoverflow.com/questions/28608015/continuous-integration-vs-continuous-delivery-vs-continuous-deployment&quot;&gt;Continuous Integration vs. Continuous Delivery vs. Continuous Deployment&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;why-not-both&quot;&gt;Why Not Both?&lt;/h1&gt;

&lt;p&gt;These two options don’t compete with one another. They complement one another.
You can happily do them both at the same time. Emphasizing shifts what to
prioritize when improving your deployment pipeline.&lt;/p&gt;

&lt;p&gt;By applying both approaches together, you increase your odds of having
great releases. You can ship more. You will have higher confidence in each
release. The closer you get to a Golden Master branch you will have many
Last Known Good builds to choose from.&lt;/p&gt;

&lt;p&gt;The more thorough your automated validation, the more confidence you have
in each build you make. Reduce the overhead and effort for each release.
Keep improving your releases and try Continuous Delivery or Continuous
Deployment.&lt;/p&gt;

&lt;p&gt;Choose the best from each approach and apply it to your deployment pipeline.
Then get to work shipping great software.&lt;/p&gt;

</content>
</entry>


<entry>
  <title type="html"><![CDATA[Safe Ordering For Breaking Changes]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/safe-ordering-breaking-changes/" />
  <id>http://www.smaclellan.com/posts/safe-ordering-breaking-changes</id>
  <published>2015-10-26T19:51:07-04:00</published>
  <updated>2015-10-26T19:51:07-04:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;When you decide to make
breaking changes to your API there is a safe easy order to follow. If you
don’t you will make consumers of your API very sad. In this post I am going to
explain how we update our APIs and slowly introduce changes which
otherwise would horribly break them.&lt;/p&gt;

&lt;p&gt;You have Version 1.0 live. It is great and you love it! Everyone is using it and
telling all their friends about it.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;curl http://yourservice.com/api/v1.0/route &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; POST &lt;span class=&quot;nt&quot;&gt;--data&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;data /&amp;gt;&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Content-Type: text/xml&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Time goes on and all is well. Out of the blue you have an epiphany. A change to
the API which is soooo much better than Version 1.0. JSON instead of XML. You could replace the old
API in place, but it would be a breaking change which would hurt all those
users of your API.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;curl http://yourservice.com/api/v2.0/route &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; POST &lt;span class=&quot;nt&quot;&gt;--data&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;{ 'data': 'booya' }&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will be okay. Take a deep breath. Begin your changes in this order:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Update the service to support both Version 1.0 and 2.0&lt;/li&gt;
  &lt;li&gt;Update all the clients to use Version 2.0&lt;/li&gt;
  &lt;li&gt;Remove support for Version 1.0&lt;/li&gt;
&lt;/ol&gt;

&lt;figure&gt;
	&lt;img title=&quot;Its as easy as 1, 2 and 3&quot; alt=&quot;The sequence of updates below&quot; src=&quot;http://www.smaclellan.com/images/safe-versionning.jpg&quot; /&gt;
&lt;/figure&gt;

&lt;p&gt;The key to this is step 1. By having both versions live at the same time users
can switch to Version B at their leisure. This is key. They are not forced
to immediately update all their clients to take the new version. Although Version 2.0 breaks Version 1.0,
temporarily supporting both makes the change safe for all the clients.&lt;/p&gt;

&lt;p&gt;Steps 2 and 3 can happen as quickly or slowly as you would like. I like to
accelerate the process to reduce the number of supported versions in the wild.
We have also left older versions alive for extended periods provided the cost
of supporting them was very low.&lt;/p&gt;

&lt;p&gt;So there you have it, a nice simple order to make breaking changes to your API
without breaking your API.&lt;/p&gt;
</content>
</entry>


<entry>
  <title type="html"><![CDATA[Drawing Ideas Out]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/drawing-ideas-out/" />
  <id>http://www.smaclellan.com/posts/drawing-ideas-out</id>
  <published>2015-10-08T19:42:07-04:00</published>
  <updated>2015-10-08T19:42:07-04:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;Listening is important. If you spend all your time talking you will miss good
ideas. We have been working closely with another team who is coming up to
speed. Instead of helping direct the project I need to shift my efforts to
drawing out their good ideas and supporting them.&lt;/p&gt;

&lt;p&gt;We had been lined up to work with another team on a project. Due to logistics it was
decided the project would be easier if they lead the development.
We would assist them and discuss different ideas, but not much else.&lt;/p&gt;

&lt;h1 id=&quot;no-monopoly-on-good-ideas&quot;&gt;No Monopoly on Good Ideas&lt;/h1&gt;

&lt;p&gt;Prior to the project starting we had spent a great deal of time thinking about
the overall problem and potential solutions. The affected code would integrate
heavily into what we have done. Over time we have become subject matter experts
which has led to strong opinions about how things should be done.&lt;/p&gt;

&lt;p&gt;Like many developers I want to solve problems. You know build cool stuff! This
normally involves rolling up my sleeves and diving in. I like choosing how to
approach different problems and then working with our team to get it done.&lt;/p&gt;

&lt;p&gt;However, to succeed on this project I need to put aside my own ideas and
listen. Instead of starting with my own opinion, I need to facilitate the
conversation so their ideas shine through. My co-worker Daryl put it
fantastically, &lt;em&gt;“they have good ideas, we need to help draw them out”&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Arguing for my own ideas would be counterproductive. The goal is not to show
off how smart we are or build up my ego. We could hand them over the master
plan we would have followed and miss the mark completely. It would
kill the project and crush any autonomy the other team has.&lt;/p&gt;

&lt;p&gt;The point is to make the project a success and help our clients. Together, we
need to focus on shipping great software to meet the client needs.&lt;/p&gt;

&lt;h1 id=&quot;the-great-ideas-are-waiting&quot;&gt;The Great Ideas Are Waiting&lt;/h1&gt;

&lt;p&gt;The other team has great developers who are going to do a fantastic job. While
we might have a head start in knowing the problem domain, they will be able to
come up to speed. We did. We need to give them the space to solve their own
problems and to ask questions which will help them come to their own
solutions.&lt;/p&gt;

&lt;p&gt;Lately they have been wrestling through various challenges. It has been fun
discussing potential options with them. Every conversation goes a little
deeper. They have been learning a lot and are doing well.&lt;/p&gt;

&lt;p&gt;Their solution looks different than how I pictured it in my mind and I think
that is fantastic! It shows they are finding their own path.&lt;/p&gt;

&lt;p&gt;The great ideas are waiting. Together we can draw them out.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Thanks FTO for being patient with us and the continuing discussions. I cannot
wait until V1 ships. Thanks Daryl for being awesome and letting me learn from
you. Thank you Travis for gently reminding me I don’t
have a monopoly on good ideas and coming up with the phrase.&lt;/em&gt;&lt;/p&gt;
</content>
</entry>


<entry>
  <title type="html"><![CDATA[How Preflights Changed Our World]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/preflights-changed-our-world/" />
  <id>http://www.smaclellan.com/posts/preflights-changed-our-world</id>
  <published>2015-09-29T18:37:07-04:00</published>
  <updated>2015-09-29T18:37:07-04:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;Preflight builds changed our world. They have made master more stable and are an
essential part of every pull request. A preflight build or preflight is a build
which runs a portion of your CI on a branch being developed. We have introduced
preflights into several projects and I can say the results are dramatic. I don’t want to
merge my changes without first passing the preflight build.&lt;/p&gt;

&lt;p&gt;It has been a while since we started using preflights.
Daryl and a few others first introduced then to our bigger projects. Lately we
have been trying to apply the same techniques to smaller projects.&lt;/p&gt;

&lt;p&gt;Our preflights are similar to our complete CI process in that they build, test,
package and deploy the project. Where they differ is how comprehensive they
are while testing and the deployment complexity. To speed up the process we run
only the most critical portions of the CI process and simplify the deployment.
We want the developers to get faster feedback while still providing more
thorough validation.&lt;/p&gt;

&lt;h1 id=&quot;how-did-we-get-here&quot;&gt;How did we get here?&lt;/h1&gt;

&lt;p&gt;Last year a small team of solid developers added preflights to a critical
project. They made the entire process incredibly simple which I think is why it
took off the way it did. The process goes like this:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Creating a pull request automatically starts a preflight build&lt;/li&gt;
  &lt;li&gt;As the preflight progresses the pull request is updated&lt;/li&gt;
  &lt;li&gt;When the preflight finishes or fails an email is sent&lt;/li&gt;
  &lt;li&gt;More preflights can be triggered as needed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We had a CI pipeline, but it would often break due to the number of developers
committing to it. It also took hours to run which meant if it broke it would
take a long time to get back to normal. This would become even worst if new
changes were committed on top of the broken code.&lt;/p&gt;

&lt;p&gt;Many developers would instead try to be extremely careful with their changes.
They would do a great deal of extra testing and investigation up front. This was
time consuming and could not cover all possible changes the developers
could make. It still left room from human error and other merge problems.&lt;/p&gt;

&lt;p&gt;Preflights allowed us to raise the bar for code before it was merged into
master. As soon as the preflights were added people started using them. They were
so simple to use and for typical changes would happen automatically. Quickly
master became more stable and people started focusing more on the results the
preflights were showing.&lt;/p&gt;

&lt;p&gt;The started a virtuous cycle, giving the preflights more attention which led to further improvements.
Contributors started to iterate on improving what was covered by the preflight
tests. Flaky tests became more problematic because they would throw off test
results. Over time bad tests were systematically identified and fixed.&lt;/p&gt;

&lt;p&gt;Now almost a year later I don’t think I could work on the project without using the
preflights. The added confidence and stability from the preflights is dramatic. We can
easily iterate on the code and build breaks are much rarer. All developers can
benefit from having their changes validated better before merging.&lt;/p&gt;

&lt;h1 id=&quot;the-next-project&quot;&gt;The Next Project&lt;/h1&gt;

&lt;p&gt;Daryl, who had been on the original team implementing preflights wanted to bring them to our
team. We were about to restart a project and planned to change the
architecture while keeping the overall behaviour intact.
He advocated setting up preflights early in the project and thought they would
help keep our code stable. We agreed and I soon set them up.&lt;/p&gt;

&lt;p&gt;Our normal workflow was:&lt;/p&gt;

&lt;figure class=&quot;image-center&quot;&gt;
	&lt;img title=&quot;Around and around with no preflights to be found.&quot; alt=&quot;Our workflow before having preflights.&quot; src=&quot;http://www.smaclellan.com/images/posts/Preflights/Before.png&quot; /&gt;
	&lt;figcaption&gt;
	Make code, create pull request, merge, run CI, release, repeat.
	&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;At first the difference in our behaviour was not pronounced.
Preflights slightly shifted the workflow to become:&lt;/p&gt;

&lt;figure class=&quot;image-center&quot;&gt;
	&lt;img title=&quot;The same old cycle with preflights keeping master sound.&quot; alt=&quot;Our workflow after having preflights.&quot; src=&quot;http://www.smaclellan.com/images/posts/Preflights/After.png&quot; /&gt;
	&lt;figcaption&gt;
	Make code, create pull request, pass the preflight, merge, run CI, release, repeat.
	&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;As development accelerated, the preflights caught breaking changes we had not intended.
Defects which would have derailed development were stopped dead in their tracks.
Our master became more stable despite our active development.&lt;/p&gt;

&lt;p&gt;As I continued to use the preflights I started to experiment. If I was confident
in my changes sometimes I would kick off a preflight early to see whether what
I had done was valid. The tests were more comprehensive than my local build
and I could get better feedback early. This allowed me to work more
asynchronously less babysitting builds. The notifications would let me know
whether my changes were good or bad.&lt;/p&gt;

&lt;p&gt;It all clicked for me when I accidentally merged too soon. I had made some
hasty changes and merged prior to the preflight passing. My changes broke
master in a way which would have been caught by the preflights. It has been
weeks of using the preflight builds and this was the first time I could remember
having broken our master.&lt;/p&gt;

&lt;p&gt;Thanks to the preflights we rarely broke our master. The preflights made it
very clear when changes would cause problems. Instead of relying on humans
being careful, we could now let machines protect us from ourselves.&lt;/p&gt;

&lt;h1 id=&quot;by-the-numbers&quot;&gt;By the Numbers&lt;/h1&gt;

&lt;p&gt;I feel like this post is less cool without qualifying the exact improvements
and how many breakages we prevented. Sadly we have been using preflights long enough and aggressively
purge old build history. While I was not able to get a comparison from before
the preflights, I was able to look at the statistics on our pull requests
for part of September.&lt;/p&gt;

&lt;p&gt;We had 43 pull requests including hundreds of commits which triggered over a
hundred builds. 98% of pull requests had a passing build with my accidental
merge being the one pull request without a passing build. We found 42% of our
pull request failed one or more builds and needed more work. In other words,
18/43 pull requests were prevented from breaking our codebase.&lt;/p&gt;

&lt;p&gt;Our failing preflights looks quite high without context. I do feel a little bad
about these numbers, but given the circumstances and project they may be
reasonable. We essentially rewrote the internals of a project while preserving
the overall behaviour. We were very active with hundreds of commits across
several developers.&lt;/p&gt;

&lt;p&gt;I view the preflights for our project as a success. Each of
those failures could have broken master and delayed the entire team. Instead
failures were stopped before they were merged.&lt;/p&gt;

&lt;h1 id=&quot;tradeoffs-and-limitations&quot;&gt;Tradeoffs and Limitations&lt;/h1&gt;

&lt;p&gt;This might sounds like rainbows and unicorns. Like everything there are tradeoffs and
limitations. We learnt several lessons from the process and have more areas to
improve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Our end to end process is slower&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The preflights nearly double the
amount of time required to go from initial commit to deployed to
production. Overlapping preflights with code reviews helps mitigate this.
It is great for complex reviews which are longer than the preflight, but
for simple changes the extra waiting is annoying.&lt;/p&gt;

&lt;p&gt;We have been able to speed up the preflight feedback by running more of the process in
parallel. Running in parallel has increased our complexity and led to other
challenges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Limited coverage leaves gaps&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We have extended tests which require more
hardware or special tools. We cannot use these special assets for every
preflight. We also chose to run more important tests in the preflight and
leave more comprehensive validation for the existing CI pipeline. This has
meant there are gaps in our coverage where issues can sneak in.&lt;/p&gt;

&lt;p&gt;We have iteratively improved this process by filling in the larger gaps we find and
moving tests into the preflight from the CI. Running more of the build in parallel has allowed us to
increase the amount we can validate in a given amount of time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Harder Recovery&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If an error does sneak through the preflight or is merged
too soon it is harder to get back to normal. When errors occurred before having
preflights developers would often try to fix the change by pushing more changes.
With preflights the new fix must also pass a preflight which makes fixing the
problem and getting back to green harder.&lt;/p&gt;

&lt;p&gt;To counteract this we try to revert the change immediately and bypassing the
preflights. In this case we know the code worked before and should continue
working without the added changes. We then fix the issue in a separate pull
request. Reverting problematic commits is a common practice for CI and is
even more important to do when using preflights.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dependencies add complexity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For the both the initial project and our new project
additional dependencies make the preflights more complicated. The ideal would be
if all changes could be validated by the preflight. This harder when
incorporating third party services or managing external configuration.
Coordinating updates and performing them safely is important to not break
the preflights. We have had a few breaks caused by updating the configuration
too soon or the project being tested changing data badly which broke existing
deployments.&lt;/p&gt;

&lt;p&gt;Our typical approaches have been to reduce the extra dependencies, keep the
contracts relatively stable or version the other components. This is a big area
for improvement and challenge for our projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stability is paramount&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Intermittent failures make the preflights less
effective. The entire system, services and scripts need to be consistent.
We want the pass/fail from the preflights to be a clear indication of whether
your code should be merged or not. When the preflights randomly fail it is easy
to lose trust in their results.&lt;/p&gt;

&lt;p&gt;As we continue to iterate on the process we have tried to stabilize any
problematic components. A common offender was sensitive integration tests
which we have slowly fixed. We have added extra redundancy and monitoring to
vital services.&lt;/p&gt;

&lt;p&gt;We want to make improvements to preflights safely. This means making small
changes which are also validated by the preflights. Any change
which cannot be validated by the preflights should be the exception and should
be tested thoroughly before being merged.&lt;/p&gt;

&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;

&lt;p&gt;Using preflight builds has dramatically made our projects more stable. We have
noticed big improvements with our first few projects. We have continued to
refine how preflights interact with our processes. They have changed how we work.&lt;/p&gt;

&lt;p&gt;I think adding preflights early will be important for new projects. We know
CI is essential for all our projects. Preflight builds take this to the next
level and find problems before they reach master.&lt;/p&gt;

&lt;p&gt;If you are have troubles with stability or want a rock solid master branch then try using preflights.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Thanks to the original team who put together the first set of preflights. They have
definitely saved my bacon and I appreciate your effort to get them introduced.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks Daryl for promoting preflight builds within the team. It has made our
lives better and kept the code stable.&lt;/em&gt;&lt;/p&gt;
</content>
</entry>


<entry>
  <title type="html"><![CDATA[Programming Practice]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/programming-practice/" />
  <id>http://www.smaclellan.com/posts/programming-practice</id>
  <published>2015-09-23T19:34:07-04:00</published>
  <updated>2015-09-23T19:34:07-04:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;Lately I have been having fun doing programming problems online. They are a
nice way to go over exercises and practice various techniques.&lt;/p&gt;

&lt;p&gt;I think it is important to program for fun. Put away your normal work and go
hack on something. There is no pressure or deadlines. Programming because
you want to.&lt;/p&gt;

&lt;p&gt;My coworker wanted some feedback on some problems he had been doing.
The site he used was &lt;a href=&quot;http://exercism.io/&quot;&gt;exercism.io&lt;/a&gt;. It has a number of problems in
different languages for various levels of difficulty. All the problems include
a short description and unit tests which your solution should pass. You can see
and comment on solutions by other people. The one catch is you must have first
solved the problem yourself. I have been getting into some of the problems
lately at the cost of my regular blog posts :(.&lt;/p&gt;

&lt;p&gt;For a while I was competing with some friends to see who could get further on
&lt;a href=&quot;https://projecteuler.net/&quot;&gt;Project Euler&lt;/a&gt;. The site is filled with various math problems which are
best solved using programming. Sure you might be able to calculate a few by
hand, but the real fun is writing code to find the solution. Some problems can
be brute forced whereas others need a more intelligent solution.&lt;/p&gt;

&lt;p&gt;I also enjoy reviewing various algorithms and techniques though the
regular updates from &lt;a href=&quot;http://codingforinterviews.com/&quot;&gt;Coding for Interviews&lt;/a&gt;. They
review some fundamental data structure or algorithm and provide sample problems.
Less raw programming fun and more solid practice.&lt;/p&gt;

&lt;p&gt;There you have it. A few handy fun sites to find new challenges:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://exercism.io/&quot;&gt;exercism.io&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://projecteuler.net/&quot;&gt;Project Euler&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://codingforinterviews.com/&quot;&gt;Coding for Interviews&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Go code!&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;Bonus:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Coding for Interviews has a list of other &lt;a href=&quot;http://codingforinterviews.com/practice&quot;&gt;practice&lt;/a&gt; sites and why they
like them. I have not seen most of the sites before and think they could be
fun! On their is list &lt;a href=&quot;http://www.codewars.com/&quot;&gt;codewars&lt;/a&gt; which offers community curated
problems and a ranking system. My brother in-law raves about them and really
enjoys their problems.&lt;/p&gt;

</content>
</entry>


<entry>
  <title type="html"><![CDATA[Parameterized Tests Made Simple]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/parameterized-tests-made-simple/" />
  <id>http://www.smaclellan.com/posts/parameterized-tests-made-simple</id>
  <published>2015-09-17T20:00:07-04:00</published>
  <updated>2015-09-17T20:00:07-04:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;I often find my tests look very similar. The behaviour of the tests are
exactly the same with different input and output data. Data driven or parameterized tests in &lt;a href=&quot;http://www.nunit.org&quot;&gt;NUnit&lt;/a&gt;
are a great way to combine tests with different values and the same behaviour.
In this post I will show you how to use NUnit’s features to create parameterized tests.&lt;/p&gt;

&lt;div class=&quot;disclaimer&quot;&gt;
&lt;p&gt;
If you like this post and want to go deeper, I would like to recommend
&lt;a href=&quot;https://github.com/gowland/nunit-docs/blob/master/valuesource-tutorial.md&quot;&gt;&quot;NUnit ValueSource: the Complete Tutorial&quot;&lt;/a&gt; by Robert Gowland. There are alot more examples which show
how to use the various attributes together. This post is just a teaser. Go there
when you are done if you want the full story.
&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;In order to demo parameterized test I will be using a simple &lt;code class=&quot;highlighter-rouge&quot;&gt;StringCalculator&lt;/code&gt; based
on the &lt;a href=&quot;http://osherove.com/tdd-kata-1/&quot;&gt;String Calculator kata&lt;/a&gt;. The class, &lt;code class=&quot;highlighter-rouge&quot;&gt;StringCalculator&lt;/code&gt; has one
method &lt;code class=&quot;highlighter-rouge&quot;&gt;Add&lt;/code&gt; which takes in a string containing delimited numbers as input
and returns the sum of the numbers.&lt;/p&gt;

&lt;p&gt;Written normally each test would call &lt;code class=&quot;highlighter-rouge&quot;&gt;Add&lt;/code&gt; with different input and then verify the total. Using parameterized test
cases we can easily add new cases which clearly show how the input and the total are related.&lt;/p&gt;

&lt;p&gt;If I was to write these tests without using parameters I would need to repeat
nearly identical code for each test. The code for the tests would look like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;NUnit.Framework&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;[TestFixture]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SimpleStringCalculatorTests&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Add_EmptyString_ReturnsZero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;StringCalculator&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StringCalculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AreEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Add_SingleNumber_ReturnsTheNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;StringCalculator&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StringCalculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AreEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Add_TwoNumbers_ReturnsTheTotal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;StringCalculator&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StringCalculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1,2&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AreEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We can do better. Thankfully NUnit allows you to create
&lt;a href=&quot;http://www.nunit.org/index.php?p=parameterizedTests&amp;amp;r=2.5.10&quot;&gt;parameterized tests&lt;/a&gt; using special attributes.
Using these attributes, we can dramatically reduce the duplicate code in the
tests.&lt;/p&gt;

&lt;p&gt;In order to use these attributes you will need to do the following steps:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Promote the constant values you want to parametize into parameters on the test method&lt;/li&gt;
  &lt;li&gt;Apply the attributes to define the cases you want to test&lt;/li&gt;
  &lt;li&gt;…&lt;/li&gt;
  &lt;li&gt;Profit&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Refactoring the tests above my I am left with a single test method:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;NUnit.Framework&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;[TestFixture]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RefactoredStringCalculatorTests&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Warning: This will not run in its current state.&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//          We need to add the attributes first!&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Add_SimpleInputs_AddsNumbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expectedTotal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;StringCalculator&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StringCalculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AreEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expectedTotal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now we are ready to explore what the different attributes do.&lt;/p&gt;

&lt;h2 id=&quot;complete-cases&quot;&gt;Complete Cases&lt;/h2&gt;

&lt;p&gt;The first set of attributes, &lt;code class=&quot;highlighter-rouge&quot;&gt;TestCase&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;TestCaseSource&lt;/code&gt;, define complete test cases.
You can think of them like rows
in a table containing values for each of the test’s parameters. The test framework will call the test
method one test case at a time with all the test case’s parameter values.&lt;/p&gt;

&lt;p&gt;Both attributes apply to the test method itself. &lt;code class=&quot;highlighter-rouge&quot;&gt;TestCase&lt;/code&gt; directly contains
values for its test case(s) whereas &lt;code class=&quot;highlighter-rouge&quot;&gt;TestCaseSource&lt;/code&gt; refers to another method/type which
will supply the values. I will explain the difference more below.&lt;/p&gt;

&lt;h3 id=&quot;testcase-attribute&quot;&gt;TestCase Attribute&lt;/h3&gt;

&lt;p&gt;The &lt;a href=&quot;http://www.nunit.org/index.php?p=testCase&amp;amp;r=2.6.4&quot;&gt;TestCase&lt;/a&gt; attribute is applied directly to a single test and
provide values for one test case. If you want multiple cases add more copies of
the attribute! The values provided to the TestCase attribute line up with their matching parameter. More
options can be configured using named parameters on the attribute, such as the
test name or expected exceptions.&lt;/p&gt;

&lt;p&gt;The main drawback to this approach is only simple compile time constants can be
used as parameters. This simplicity is not all bad. It helps keep the tests
focused and avoids having more complicated logic sneak into your test setup.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;NUnit.Framework&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;[TestFixture]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TestCaseStringCalculatorTests&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;TestCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;TestCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;TestCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1,2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Add_SimpleInputs_AddsNumbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expectedTotal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;StringCalculator&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StringCalculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AreEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expectedTotal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;testcasesource-attribute&quot;&gt;TestCaseSource Attribute&lt;/h3&gt;

&lt;p&gt;The &lt;a href=&quot;http://www.nunit.org/index.php?p=testCaseSource&amp;amp;r=2.6.4&quot;&gt;TestCaseSource&lt;/a&gt; attribute is applied to the test method
like the &lt;code class=&quot;highlighter-rouge&quot;&gt;TestCase&lt;/code&gt; attribute. This method delegates creating parameter values
to other methods, fields or types. Using the &lt;code class=&quot;highlighter-rouge&quot;&gt;TestCaseSource&lt;/code&gt; is more
flexible and can be used to provide more complicated parameter types. Within
the source method you can reuse objects/data for multiple tests. The same
source method can also be reused for multiple tests.&lt;/p&gt;

&lt;p&gt;To use &lt;code class=&quot;highlighter-rouge&quot;&gt;TestCaseSource&lt;/code&gt; you must provide a &lt;code class=&quot;highlighter-rouge&quot;&gt;sourceName&lt;/code&gt; and/or &lt;code class=&quot;highlighter-rouge&quot;&gt;sourceType&lt;/code&gt;.
If only &lt;code class=&quot;highlighter-rouge&quot;&gt;sourceName&lt;/code&gt; is used the field/method is assumed to be in the same
class as the test.&lt;/p&gt;

&lt;p&gt;The type of data provided by the source is very flexible.  For simple parameters
normal arrays or &lt;code class=&quot;highlighter-rouge&quot;&gt;object[]&lt;/code&gt; can be returned from the source.
I prefer using &lt;code class=&quot;highlighter-rouge&quot;&gt;IEnumerable&amp;lt;TestCaseData&amp;gt;&lt;/code&gt; which has extra options like &lt;code class=&quot;highlighter-rouge&quot;&gt;TestCase&lt;/code&gt; for configuring the test such as test name. Review the
&lt;a href=&quot;http://www.nunit.org/index.php?p=testCaseSource&amp;amp;r=2.6.4&quot;&gt;TestCaseSource&lt;/a&gt; documentation for the additional rules for source types.&lt;/p&gt;

&lt;p&gt;In this example we will use &lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;AddCases&quot;&lt;/code&gt; as our source
method which returns &lt;code class=&quot;highlighter-rouge&quot;&gt;IEnumerable&amp;lt;TestCaseData&amp;gt;&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Collections.Generic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;NUnit.Framework&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;[TestFixture]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TestCaseSourceStringCalculatorTests&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestCaseData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;AddCases&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TestCaseData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TestCaseData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TestCaseData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1,2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TestCaseSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;AddCases&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Add_SimpleInputs_AddsNumbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expectedTotal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;StringCalculator&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StringCalculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AreEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expectedTotal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;single-parameters&quot;&gt;Single Parameters&lt;/h2&gt;

&lt;p&gt;Another option is to apply attributes to the test parameters. They can behave
like &lt;code class=&quot;highlighter-rouge&quot;&gt;TestCase&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;TestCaseSource&lt;/code&gt; for a single parameter. For tests with
multiple parameters the behaviour is more complicated and can be used to create
many test cases.&lt;/p&gt;

&lt;p&gt;The following attributes are placed on a parameter and control a single parameter’s values:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.nunit.org/index.php?p=values&amp;amp;r=2.6.4&quot;&gt;Values&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.nunit.org/index.php?p=valueSource&amp;amp;r=2.6.4&quot;&gt;ValueSource&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.nunit.org/index.php?p=random&amp;amp;r=2.6.4&quot;&gt;Random&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.nunit.org/index.php?p=range&amp;amp;r=2.6.4&quot;&gt;Range&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whereas the following attributes are applied to the method and define how values
from multiple parameters are combined to create complete test cases:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.nunit.org/index.php?p=combinatorial&amp;amp;r=2.6.4&quot;&gt;Combinatorial&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.nunit.org/index.php?p=sequential&amp;amp;r=2.6.4&quot;&gt;Sequential&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.nunit.org/index.php?p=pairwise&amp;amp;r=2.6.4&quot;&gt;Pairwise&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Clear as mud? That is okay! I have a few examples to clarify how to use these
attributes.&lt;/p&gt;

&lt;h3 id=&quot;values-attribute&quot;&gt;Values Attribute&lt;/h3&gt;

&lt;p&gt;This simple example shows using the &lt;code class=&quot;highlighter-rouge&quot;&gt;Values&lt;/code&gt; attribute inline with a single
parameter. The values from the attribute each create a single test case to be
executed. This behaves like &lt;code class=&quot;highlighter-rouge&quot;&gt;TestCase&lt;/code&gt; for a single parameter.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;NUnit.Framework&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;[TestFixture]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ValuesStringCalculatorTests&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Add_NullOrBlank_ReturnsZero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;\t&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;\n&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;StringCalculator&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StringCalculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AreEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;valuesource-attribute&quot;&gt;ValueSource Attribute&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;ValueSource&lt;/code&gt; provides values from a method, or field or type. Just how
&lt;code class=&quot;highlighter-rouge&quot;&gt;Values&lt;/code&gt; behaves like &lt;code class=&quot;highlighter-rouge&quot;&gt;TestCase&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;ValueSource&lt;/code&gt; behaves like
&lt;code class=&quot;highlighter-rouge&quot;&gt;TestCaseSource&lt;/code&gt;. In this example I am using the &lt;code class=&quot;highlighter-rouge&quot;&gt;NullOrBlankCases&lt;/code&gt; array
to determine the values for each test case.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;NUnit.Framework&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;[TestFixture]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ValueSourceStringCalculatorTests&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NullOrBlankCases&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;\t&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;\n&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Add_NullOrBlank_ReturnsZero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ValueSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;NullOrBlankCases&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;StringCalculator&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StringCalculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AreEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;range-and-random-attributes&quot;&gt;Range and Random Attributes&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Range&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;Random&lt;/code&gt; are two special cases for specifying numbers.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Range&lt;/code&gt; generates test cases between a starting point, an end point and
optionally the step size between each test case. In the example below, I use
&lt;code class=&quot;highlighter-rouge&quot;&gt;Range&lt;/code&gt; starting at 2 and going to 10 in steps of 2 to produce the cases
2, 4, 6, 8, 10.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;NUnit.Framework&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;[TestFixture]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RangeStringCalculatorTests&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Add_EvenNumbersBetweenTwoAndTen_ReturnsTheNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;StringCalculator&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StringCalculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AreEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Random&lt;/code&gt; uses random numbers to create multiple test cases. The values can
optionally be constrained between two values. Be careful. The random numbers
might be very large or very small which can cause your tests to randomly fail.
The example below creates 5 tests cases for random numbers between 0 and 10.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;NUnit.Framework&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;[TestFixture]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RandomStringCalculatorTests&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Add_RandomNumberBetweenZeroAndTen_ReturnsTheNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;StringCalculator&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StringCalculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AreEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;combining-multiple-parameters&quot;&gt;Combining Multiple Parameters&lt;/h3&gt;

&lt;p&gt;Cool! Dealing with a single parameter is really easy. How does it work with
multiple parameters? This is where the other attributes are used to control the
behaviour for combining the values from all the parameters. They are placed on the
method and are mutually exclusive.&lt;/p&gt;

&lt;p&gt;The default behaviour is to evaluate all combinations of the parameters.
You can specify this behaviour explicitly using the &lt;code class=&quot;highlighter-rouge&quot;&gt;Combinatorial&lt;/code&gt; attribute
on the method. Be careful, this can generate many tests if you have lots of values
or parameters.&lt;/p&gt;

&lt;p&gt;You can combine values from the parameters in the order they are declared using the &lt;code class=&quot;highlighter-rouge&quot;&gt;Sequential&lt;/code&gt; attribute.
This is like treating the values for each parameter as a column in a table.
Each row is then forms a single test case. I try to use this option sparingly.
Often the parameter values do not line up visually and it can be hard to
determine what the cases will be. The example below will have the following
cases executed by the attribute:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;””, 0&lt;/li&gt;
  &lt;li&gt;“1”, 1&lt;/li&gt;
  &lt;li&gt;“1,2”, 3&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;NUnit.Framework&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;[TestFixture]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ParameterStringCalculatorTests&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TestNumbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1,2&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TestTotals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Sequential&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Add_SimpleInputs_AddsNumbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ValueSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;TestNumbers&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ValueSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;TestTotals&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expectedTotal&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;StringCalculator&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StringCalculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AreEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expectedTotal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The last attribute which modifies how the parameters are combined is &lt;code class=&quot;highlighter-rouge&quot;&gt;Pairwise&lt;/code&gt;.
It uses a heuristic to create cases covering every possible pair of parameters.
The intend is to generate fewer cases than &lt;code class=&quot;highlighter-rouge&quot;&gt;Combinatorial&lt;/code&gt; while still
providing good coverage. I have not used it on a project before. If you
have too many tests caused by using &lt;code class=&quot;highlighter-rouge&quot;&gt;Combinatorial&lt;/code&gt; you may want to try using
this attribute.&lt;/p&gt;

&lt;h2 id=&quot;go-test-with-cases&quot;&gt;Go Test, With Cases!&lt;/h2&gt;

&lt;p&gt;I hope you enjoyed this overview of the how to create test cases with NUnit. To
make it easy to work through the examples I have uploaded a &lt;a href=&quot;https://github.com/smaclell/nunit-testcase-examples&quot;&gt;repository&lt;/a&gt; to
github with sample code for each of the cases. I even included a few bonus
examples I made along the way. Enjoy.&lt;/p&gt;

&lt;p&gt;Test cases are great fun and can help cut down on duplication in your tests.
If you think all your tests all look the same, try using test cases to clean them up.&lt;/p&gt;

</content>
</entry>


<entry>
  <title type="html"><![CDATA[Investing in your Code]]></title>
 <link rel="alternate" type="text/html" href="http://www.smaclellan.com/posts/investing-in-your-code/" />
  <id>http://www.smaclellan.com/posts/investing-in-your-code</id>
  <published>2015-09-10T23:39:07-04:00</published>
  <updated>2015-09-10T23:39:07-04:00</updated>
  <author>
    <name>Scott MacLellan</name>
    <uri>http://www.smaclellan.com</uri>
    <email>scott@smaclellan.com</email>
  </author>
  <content type="html">&lt;p&gt;Taking code and transforming how it fits together without breaking it is an
art. It is also great fun! However, before you start I think you should
understand whether your efforts will be worthwhile. This post examines
different stages in the code life cycle and how they affect how much
you should invest in cleaning up code.&lt;/p&gt;

&lt;p&gt;I like having a job. Every day when I go to work I am happy they let me in so I can
code up a storm. The important difference between my job and a really kick ass
hobby is getting paid. We are a business and staying in business is
important for me and our customers.&lt;/p&gt;

&lt;p&gt;Taking the time to make deep changes is a good thing. The larger the impact of
the change the more important it is to understand why it will be valuable in the long term.
What will the impact be? How will the change help your users?&lt;/p&gt;

&lt;p&gt;When it comes to refactoring and maintaining code I think this especially tricky. The more entangled
the code is the more I want to “fix” it. Beautiful code is something to be
admired and even pursued, but only as a means to an end. At the end of the day
you still have to ship and support your product.&lt;/p&gt;

&lt;p&gt;I think it is important to think about when to update code, how much to
change and what the long term benefit will be of what you are doing. Balancing
your desire to do the right thing and where to focus your efforts will result
in a better product with less effort.&lt;/p&gt;

&lt;h1 id=&quot;a-new-dawn&quot;&gt;A New Dawn&lt;/h1&gt;

&lt;figure class=&quot;image-center&quot;&gt;
	&lt;a data-flickr-embed=&quot;true&quot; href=&quot;https://www.flickr.com/photos/michaelmattiphotography/9448609846/&quot; title=&quot;Evergreen Mountain Lookout Sunset by Michael Matti&quot;&gt;
		&lt;img src=&quot;https://farm8.staticflickr.com/7415/9448609846_c47a62b97a_z.jpg&quot; width=&quot;640&quot; height=&quot;426&quot; alt=&quot;Evergreen Mountain Lookout Sunset by Michael Matti&quot; /&gt;
	&lt;/a&gt;
	&lt;figcaption&gt;
		Evergreen Mountain Lookout Sunset by &lt;a href=&quot;https://www.flickr.com/photos/michaelmattiphotography/&quot;&gt;Michael Matti&lt;/a&gt;,
		used under &lt;a href=&quot;https://creativecommons.org/licenses/by-nc/2.0/&quot;&gt;Creative Commons 2.0 BY-NC&lt;/a&gt;
	&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Three categories of code are worth investing: your application’s critical sections,
defect filled areas
and where you plan on doing work in the future. These categories often overlap and
cause the code to be more important. There is a higher probability
you will be working on or troubleshooting these areas in the future. Do a favour for
future you and leave the code better than you found it.&lt;/p&gt;

&lt;p&gt;Every project has features which are more important. Often this will be the
reason why the project was started in the first place. The fundamental
business process only this project performs or the one page every user loves.
Caring for core sections of any project is worthwhile.&lt;/p&gt;

&lt;p&gt;Important feature need to work every time. A regression in a critical tool is
awful for the user experience. Having great test coverage and simplifying the
code around your core features will help keep the code easy to maintain and
updates as requirements change.&lt;/p&gt;

&lt;p&gt;Larger refactoring exercises are reasonable since improvements will have a bigger
impact for your users. Organic growth and tacked on features can lead to areas
which do not fully make sense. Restructuring classes to better align and
simplify how they interact is justified. In the critical section it is more
important to prevent causing issues with your changes. Be careful.&lt;/p&gt;

&lt;p&gt;Infamous code riddled with bugs is another good place to invest time in.
This is another critical section for all the wrong reasons. The attention it
gets is bad and your users will start to notice repeat issues.
&lt;a href=&quot;http://www.testingexcellence.com/defect-clustering-in-software-testing/&quot;&gt;Defects tend to cluster together&lt;/a&gt; and cleaning up the whole area can be a good approach. Reducing complexity
which leads to more defects is even better. However, if you don’t plan on
supporting the functionality despite the defects this is dead code in disguise and you should move on.&lt;/p&gt;

&lt;p&gt;Adding functionality and plan to add more in the future? The amount of time you
plan on spending in an area or integrating with it is a good way to decide how
much refactoring/cleanup you want to do. Setting up for new changes is a great
reason to refactor. After you have implemented new functionality you could
consolidate the existing classes.&lt;/p&gt;

&lt;h1 id=&quot;unsure&quot;&gt;Unsure?&lt;/h1&gt;

&lt;figure class=&quot;image-center&quot;&gt;
	&lt;a data-flickr-embed=&quot;true&quot; href=&quot;https://www.flickr.com/photos/66176388@N00/5669437281/&quot; title=&quot;New Leaves And Old by Mark Robinson&quot;&gt;
		&lt;img src=&quot;https://farm6.staticflickr.com/5187/5669437281_84e78ff2c0_z.jpg&quot; width=&quot;640&quot; height=&quot;427&quot; alt=&quot;New Leaves And Old by Mark Robinson&quot; /&gt;
	&lt;/a&gt;
	&lt;figcaption&gt;
		New Leaves And Old by &lt;a href=&quot;https://www.flickr.com/photos/66176388@N00/&quot;&gt;Mark Robinson&lt;/a&gt;,
		used under &lt;a href=&quot;https://creativecommons.org/licenses/by-nc/2.0/&quot;&gt;Creative Commons 2.0 BY-NC&lt;/a&gt;
	&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Not sure what the future holds? If the area you working in is not important or
only needs minor changes then spending lots of time cleaning it up is not as
useful. Spending a few hours might still make sense, but days or weeks would not.
The key is balancing how much time and effort you spend doing it.&lt;/p&gt;

&lt;p&gt;What is the best thing to do if you are not sure about how much or what
maintenance would be good? Play it safe and focus on smaller improvements.
I would focus on the essential improvements: eliminating duplication and
improving the testability.&lt;/p&gt;

&lt;p&gt;Reducing duplication shrinks the amount of code you need to maintain. Starting
with a simple refactoring like &lt;a href=&quot;http://refactoring.com/catalog/extractMethod.html&quot;&gt;“Extracting a Method”&lt;/a&gt; is a
good start. I recently extracted a method to encapsulate logic which
had been copied repeatedly. Now there is one place to fix
maintain instead of the many copies.&lt;/p&gt;

&lt;p&gt;Find part of the code confusing? Afraid to make changes in an area? Wrapping
existing code in tests can help explain what is happening and make other
changes safer. Tests provide a safety net for future changes and can often be
added fairly easily. Refactoring to make code testable will help loosen heavily
coupled classes.&lt;/p&gt;

&lt;h1 id=&quot;long-frozen-over&quot;&gt;Long Frozen Over&lt;/h1&gt;

&lt;figure class=&quot;image-center&quot;&gt;
	&lt;a data-flickr-embed=&quot;true&quot; href=&quot;https://www.flickr.com/photos/chadcooperphotos/11874715865/&quot; title=&quot;Frozen Trees by Chad Cooper&quot;&gt;
		&lt;img src=&quot;https://farm3.staticflickr.com/2879/11874715865_8a2712f956_z.jpg&quot; width=&quot;640&quot; height=&quot;427&quot; alt=&quot;Frozen Trees by Chad Cooper&quot; /&gt;
	&lt;/a&gt;
	&lt;figcaption&gt;
		Frozen Trees by &lt;a href=&quot;https://www.flickr.com/photos/chadcooperphotos/&quot;&gt;Chad Cooper&lt;/a&gt;,
		used under &lt;a href=&quot;https://creativecommons.org/licenses/by/2.0/&quot;&gt;Creative Commons 2.0 BY&lt;/a&gt;
	&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Long forgotten code that has been left for dead should be avoided. It is okay for code to be “done” and not
expect to change in the future. Any effort is probably wasted or much harder
than it needs to be. Often it would be a better decision to walk away.&lt;/p&gt;

&lt;p&gt;Clients will see little benefit from the work you do to this unloved code. No matter how
much you might want to restructure the classes to perfectly separate concerns it is
not worth it.&lt;/p&gt;

&lt;p&gt;We recently declared one of our projects as dead. When we first started we wrote
a large number of tests through the UI. The tests were great when we first created them,
but eventually fell into disrepair as we moved onto other projects. We
decided it was not worth dedicating the effort to fix all the tests right now
and instead we would add new tests to eventually replace the existing code.
For us it would be better to rewrite or remove the tests than maintain them.&lt;/p&gt;

&lt;p&gt;If you must update one of these forgotten relics; get in and get out.
Don’t make the project worse than it is, but don’t stick around either.
Updating dead code is like shuffling deck-chairs on the Titanic.
Don’t you have better things to do with your time?&lt;/p&gt;

&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;

&lt;p&gt;Before you dive in think about what areas or projects would benefit the most
from your improvements. What changes will pay off of the most?&lt;/p&gt;

&lt;p&gt;Too many defects? Refactoring for testability and adding more tests could
help prevent future defects. Are you repeating the same
changes in multiple areas? Reducing duplication could help you. Try
browsing the &lt;a href=&quot;http://refactoring.com/catalog/&quot;&gt;refactoring catalog&lt;/a&gt; for more ideas.&lt;/p&gt;

&lt;p&gt;The answer will depend on your projects and time-lines. I hope this gave you
some new ways to think about when to invest and when to back off.&lt;/p&gt;

&lt;p&gt;In summary, I recommend scaling your efforts based on how important the code is and what you
plan on doing in the area.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Invest&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Critical Code? Keep it clean!&lt;/li&gt;
  &lt;li&gt;Bugs abound? Squash them down.&lt;/li&gt;
  &lt;li&gt;Plan on sticking around? Make an investment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Minor Improvements&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Not sure what to do? Stay small.&lt;/li&gt;
  &lt;li&gt;Focus on the essentials: Reduce duplication and better tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Stop&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Left for dead? Leave it be.&lt;/li&gt;
  &lt;li&gt;Do not shuffle the deck-chairs on the Titanic.&lt;/li&gt;
&lt;/ul&gt;

</content>
</entry>

</feed>
