Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm reading "Dependency Injection in .NET" by Mark Seemann (it's fantastic, and must have) and the author often uses the word "seam". But I can't understand what it means. Here is an example of using this word:

Chapter 7 explains how to compose objects in various concrete frameworks such as ASP.NET MVC, WPF, WCF, and so on. Not all frameworks support DI equally well, and even among those that do, the ways they do it differ a lot. For each framework, it can be difficult to identify the SEAM that enables DI in that framework. However, once that SEAM is found, you have a solution for all applica- tions that use this particular framework. In chapter 7, I have done this work for the most common .NET application frameworks. Think of it as a catalog of framework SEAMS.

I would be gratefull for helping me with understanding this word.

share|improve this question
3  
There are hints to what the word means on the author's blog. And since he's a member here: @MarkSeemann this one is for you :) – Yannis Jan 30 '12 at 20:19
up vote 14 down vote accepted

I think the term originates from Michael Feathers Working Effectively with Legacy Code in which he explains a seam in software as a place where two parts of the software meet and where something else can be injected. The analogy is a seam in clothing: The place where two parts are stitched together. The piece on each side only touches the other right at the seam. Back to software: If you identify the seam you have identified the place where there is a well defined interface. That is what you can leverage in DI, since such an interface allows you to replace implementation without the rest of the software being able to tell (without cheating, anyway).

share|improve this answer
4  
c2.com/cgi/wiki?SoftwareSeam - as a reference for those who don't have the book. – Yannis Jan 30 '12 at 20:22
    
great, that what I needed. Thanks a lot! – user278618 Jan 30 '12 at 20:30
    
I'm reading that book right now! – Malfist Jan 30 '12 at 21:43
7  
+1 FWIW, I introduce the concept in section 1.3.1 on page 22. – Mark Seemann Jan 30 '12 at 21:53

Building on Christian's answer, to the best of my knowledge, the term seam does originate from Feathers' book, Working Effectively with Legacy Code. The definition is on page 31:

A seam is a place where you can alter behavior in your program without editing in that place.

To give examples of what a seam is and what it isn't, consider the following Java code:

public class MyClass {
  private final Foo foo;

  public MyClass(Foo foo) {
    this.foo = foo;
  }

  public void doBunchOfStuff(BarFactory barFactory) {
    // foo.doStuff() is a seam because I can inject a mock instance of Foo
    this.foo.doStuff();

    // barFactory.makeBars() is a seam because I can replace the default
    // BarFactory instance with something else during testing
    List<Bar> bars = barFactory.makeBars();
    for(Bar bar : bars) {
      // bar.cut() is also a seam because if I can mock out BarFactory, then
      // I can get the mocked BarFactory to return mocked Bars.
      bar.cut();
    }

    // MyStaticClass.staticCall() is not a seam because I cannot replace
    // staticCall() with different behavior without calling a class besides
    // MyStaticClass, or changing the code in MyStaticClass.
    MyStaticClass.staticCall();

    // This is not a seam either because I can't change the behavior of what
    // happens when instanceCall() occurs with out changing this method or
    // the code in instanceCall().
    (new MyInstanceClass()).instanceCall();
  }
}

The seams exemplified above would be seams unless:

  1. The class being injected is final.
  2. The method being called is final.

Basically, seams facilitate unit testing. I can't write a unit test for MyClass because of the calls to MyStaticClass.staticCall() and (new MyInstanceClass()).instanceCall(). Any unit test for MyClass's doBunchOfStuff() method would have to test MyStaticClass.staticCall() and (new MyInstanceClass()).instanceCall() and all of their dependencies that get called. Conversely, by using non-final classes with non-final methods (or better yet - interfaces), the injected instances of Foo and BarFactory make unit tests for MyClass possible to write by facilitating mocking.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.