Littlee
Littlee

Reputation: 4327

Dependency injection in data oriented programming

In the book "Data-Oriented Programming" by Yehonathan Sharvit there's an example of how to store data to a database in Chapter 10.2:

class CatalogDB {
  static addMember(member) {
    var addMemberQuery = `INSERT
                          INTO members
                               (email, encrypted_password)
                          VALUES ($1, $2)`;
    dbClient.query(
      addMemberQuery,
      _.at(member, ["email", "encryptedPassword"]),
    );
  }
}

I'm wondering how to implement the dependency injection on the dbClient instance.

Since DOP suggests all classes should contain static methods only, does it mean the dbClient can only be a source code dependency?

import dbClient from './dbClient';
class CatalogDB { /*...*/ }

So it seems we can't have dependency injection in DOP, given there is no instance variable to hold the dbClient.

Upvotes: 0

Views: 32

Answers (1)

Remo H. Jansen
Remo H. Jansen

Reputation: 24979

You can wrap your class declaration in a factory function:

import { dbClient, DbClient } from "./dbClient";
import * as _ from "underscore";

interface Member {
  email: string;
  encryptedPassword: string;
}

// Use this in your tests
function CatalogDBFactory(dbClient: DbClient) {
  class _CatalogDB {
    static addMember(member: Member) {
      var addMemberQuery = `INSERT
                            INTO members
                                (email, encrypted_password)
                            VALUES ($1, $2)`;
      dbClient.query(
        addMemberQuery,
        _.at(member, ["email", "encryptedPassword"]),
      );
    }
  }
  return _CatalogDB;
}

// Use this in your app
export const CatalogDB = CatalogDBFactory(dbClient);

You can also return an object literal instead of using a class delcaration:

function CatalogDBFactory(dbClient: DbClient) {
  return {
    addMember: (member: Member) {
      var addMemberQuery = `INSERT
                            INTO members
                                (email, encrypted_password)
                            VALUES ($1, $2)`;
      dbClient.query(
        addMemberQuery,
        _.at(member, ["email", "encryptedPassword"]),
      );
    }
  }
}

Upvotes: 0

Related Questions