Search code examples
c++dependency-injectionsmart-pointerssolid-principlessingle-responsibility-principle

Does dependency injection by smart pointers violate Single Responsibility Principle?


My concern is that when using either shared_ptr or unique_ptr I stick to one ownership model - either injected objects is shared or my own. And I think this is is secondary class responsibility - to care of injected objects lifetime.

So, does it violates SRP - assuming that class already has some responsibility.

Some simple example:

  class Calculator {
  public:
      Calculator(std::unique_ptr<Adder> adder) : adder(adder) {}
      void add();
  private:
      std::unique_ptr<Adder> adder;
  };

When design changes - so I will have many different calculators - then I need to change unique_ptr to shared_ptr. So even if Calculator main responsibility (to calculate) did not change - I need to change the class.

Wouldn't be better to use simple references for injected objects - and just left the responsibility of injected objects lifetime to some other classes?


Solution

  • No, the way we kept member variables in an object is the implementation detail, and it is not related in any way to design principles like Single Responsibility Principle

    To illustrate this - you can encapsulate access to your members by some private method - this prevents the changes in class implementation when you changes from unique_ptr to shared_ptr or vice versa.

    
    private:
       Adder& add();
       Adder const& add();
    
    

    Or you can go even further and enclose Adder to some private object - thus preventing it totally from accidental access to "read" adder variable, like:

    class Calculator 
    {
       class AdderProxy
       {
       public:
           using Type = std::unique_ptr<>;
           AdderProxy(AdderType);
           void add(...);    
       };
    public:
       Calculator(AdderProxy::Type);
    
    private:
       AdderProxy adder;
    
    

    Or you can just have some DI library, like this one - and have all kind of injection hidden from application code.