Question

I am trying to get rid off static classes, static helper methods and singleton classes in my code base. Currently, they are pretty much spread over the whole code, especially so for the utility classes and the logging library. This is mainly due to the need for mocking ability as well as object-oriented design and development concerns, e.g. extensibility. I might also need to introduce some form of dependency injection in the future and would like to leave an open door for that.

Basically, the problem I have encountered is about the method of passing the commonly used references around. These are objects that are used by almost every class in the code base, such as the logging interface, the utility (helper) class interface and maybe an instance of a class that holds an internal common state for the assembly which most classes relate to.

There are two options, as far as I'm aware. One is to define a class (or an interface) that stores the common references, a context if you will, and pass the context to each object that is created. The other option is to pass each common reference to almost every class as a separate parameter which would increase the number of parameters of the class constructors.

Which one of these methods is better, what are the pros and cons of each, and is there a better method for this task?

Was it helpful?

Solution

I generally go with the context object approach, and pass the context object either to an object's constructor, or to a method -- depending on which one makes the most sense.

The context object pattern can take a few forms.

You can define an interface that has exactly the members you need, or you can generate a sort of container class. For example, when writing loosely-coupled components, I tend to have each component I implement have a matching interface, so that it can be reimplemented if desired. Then I register the objects on a "manager" object, something like this:

public interface IServiceManager
{
    public T GetService<T>();
    public T RequireService<T>();
    public void RegisterService<T>(T service);
    public void UnregisterService<T>(T service);
}

Behind the scenes there is a map from type to object, which allows me to extremely quickly assemble a large set of diverse components into a working whole. Each component asks for the others by interface, and the manager object is what glues them together. (If you correctly author your components, you can even swap out one service for another while the process is running!)

One would register a service something along these lines:

class FooService : IFooService { }

// During process start-up:
serviceManager.RegisterService<IFooService>(new FooService());

There is more overhead with this approach than with the flat-interface approach due to the dictionary lookup, but it has allowed me to build very sophisticated systems that can be easily redeployed with different service implementations. (And, as is usual, any bottlenecks I encounter are never in looking up a service object from a dictionary, but somewhere else such as the database.)

OTHER TIPS

You're going to get varied opinions, but generally passing a separate parameter to the constructor for each dependency is preferred for a few reasons:

  • It clearly defines the actual dependencies for a class - with a "context" you don't know which parts of the context are used without digging into the code.
  • Generally having a lot of parameters to a constructor is a design smell, so using constructor injection helps you sniff out design flaws.
  • When testing you can mock out individual dependencies versus having to mock an entire context

I would suggest passing as a parameter to the constructor. This has great advantage for both dependency injection and unit testability ( mocking).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top