1

When I find a concrete dependency inside an extension method, I have been attempting to remove the (concrete) dependency by parameterising it like so

// original implementation
public static List<Address> GetDuplicate(this Address address)
{
    var repository = new AddressRepository();
    return repository.FindAddress(address.Street, address.Town);
}

// 'Fixed' implementation using 'parameter injection'
public static List<Address> GetDuplicate(this Address address, IAddressRepository repository = null)
{
    repository = repository ?? new AddressRepository();
    return repository.FindAddress(address.Street, address.Town);
}

My idea was that this would invert control of the collaborating class, AddressRepository, by making sure it could be passed in by the code using the method.

Anyway when a colleague saw this they said that the code still relied on a concrete implementation and was not using IOC. Although I can see there are some downsides of the code, I'm not sure I agree that it isn't Inversion of Control since

  1. The code depends on an abstraction (IAddressRepository)
  2. Calling code can provide a different implementation.

What principle is violated with respect to IOC? Which part of the code in particular violates that principle? Simply put, is 'parameter injection' actually a thing?

  • Since there's no actual object here (it being merely a static method), I think it's just a method parameter. Dependency Injection is normally associated with class objects; parameter injection is merely one form of it. – Robert Harvey Feb 22 '15 at 15:41
  • Maybe a duplicate: programmers.stackexchange.com/questions/41254/…, and I am sure other variants of this question have been asked before, though I cannot find them just now. – Doc Brown Feb 22 '15 at 15:52
  • @RobertHarvey You're right that there's no object which contains an instance of the dependency, but the method, and therefore the class, which contains the static method still has a dependency on AddressRepository, in so far as it requires that class to exist in order for it to function. My question is, does the parameterisation of the dependency meet the requirements for "inversion of control"? Does it matter if the parameter is optional or not? – jhsowter Feb 22 '15 at 18:02
  • @DocBrown Thanks that makes for interesting reading and is certainly in the same area. But I don't think it addresses my question, which is whether or not the example above can be considered inversion of control, or dependency injection, or if it's just a somewhat handy pattern which would be further improved by factoring in some way. – jhsowter Feb 22 '15 at 18:05
  • Thanks for the clarification. I'll put together an answer shortly. – Robert Harvey Feb 22 '15 at 18:11
2

...does the parameterisation of the dependency meet the requirements for "inversion of control"?

No. That's just Dependency Injection.

Look very carefully at the Wikipedia definition for Inversion of Control:

Inversion of Control (IoC) describes a design in which custom-written portions of a computer program receive the flow of control from a generic, reusable library [or framework].

In traditional programming, the custom code that expresses the purpose of the program calls into reusable libraries to take care of generic tasks, but with inversion of control, it is the reusable code [the library or framework] that calls into the custom, or task-specific, code.

In other words, Inversion of Control is characterized by the Hollywood Principle: Don't call us, we'll call you.

I can think of at least two ways Inversion of Control can occur in everyday use. One way is by making use of the Subscriber Pattern. In event-driven UI's, we don't call the UI framework when a user clicks on a button. Rather, we subscribe to a Click event, and the UI framework calls us:

// Subscribe to Click event.
this.button1.Click += new System.EventHandler(this.button1_Click);

// Handler for click event
private void button1_Click(object sender, MyEventArgs e)
{
    // Do something when user clicks button
}

Another example of Inversion of Control is sort methods that make use of a comparator to determine the behavior of the sort with different data types. The MSDN documentation for the Linq OrderBy method gives a good example of this.

First, we create a "comparer." A comparer is a class that satisfies the IComparer interface:

public class IntegerComparer : IComparer<int>
{
    public int Compare(int i1, int i2)
    {
        return i1 - i2;
    }
}

Given an unsorted array of:

string[] unsortedArray = { "three", "six", "nine", "twelve", "fifteen", "eighteen" };

We can then use the comparer to sort the array by the number of characters in each string:

sortedArray = unsortedArray.OrderBy(a => a.Length, new IntegerComparer());

which yields the result:

six
nine
three
twelve
fifteen
eighteen

Once again, we have inverted control by relegating generic behavior to the framework, and having the framework call your custom code to get specific behavior.

Further Reading

Inversion of Control (Martin Fowler's Bliki)

  • Thanks for your answer. I think part of the confusion is the difference between IOC and DI, which, in my experience, people use synonymously. One question though - the example of the IComparer is very similar to my example. Would you say my example is IOC? If it's not, would making the parameter mandatory change that? – jhsowter Feb 22 '15 at 20:26
  • No, because in your example, the repository is not calling your code. Your code is calling the repository. Do you see the difference? You haven't inverted control. – Robert Harvey Feb 22 '15 at 21:42
  • That depends on what is 'my' code and what is 'framework' code. Are you saying that if the repository the 'framework' then it isn't IOC, but if it's the other way around (repository is 'my' code), then it is IOC? Surely if a third party came along and wrote an implementation of IAddressRepository (and also assuming the method was public) then that would be inversion of control because 'my' code is calling 'their' implementation? – jhsowter Feb 23 '15 at 13:34
  • @jhsowter: Inversion of Control is primarily a framework concept. Read Fowler. – Robert Harvey Feb 23 '15 at 15:22
  • It seems like an arbitrary distinction to me. However I can see you've stuck very closely to Fowler's definition and ultimately it seems this comes down to semantics so I have to agree. I guess unless I'm writing a "framework" then I don't need "IOC". – jhsowter Feb 24 '15 at 11:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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