The Joys of Dependency Injection Part 1 - Interfaces

Dependency injection helps you make code that is easy to maintain and test by

  • Allowing “units” of code to only be concerned with their own functionality
  • Making dependencies easily swappable without altering dependent code
  • Allowing you to mock/control dependencies during tests so that you isolate what you are testing

In Salesforce, this is made possible via Interfaces. In short, an interface is a type that you declare that has methods it contains, but not their implementation. In order for an object to be of that type, it must implement the interface and all it’s methods. Here’s a classic example:

public interface Animal{
    String speak();
}

You’ll notice that this is slightly different from a class. The method speak has no body. Instead it is declared like a variable. When looking at this you should think, “The type Animal has the method speak, which returns a String. To get use out of it, you need to have a class implement the interface.

public class Dog implements Animal{
    public String speak(){
        return 'Bark!'
    }
}

Now we have a Dog class that implements Animal. This tells the code that Dog is of type Animal. In order to do so, we had to declare that Dog implements the Animal interface and also flesh out the method speak. If you don’t implement all of the methods in the interface, you’ll get a compilation error:

Dog: Class must implement the public interface method:
 String speak() from Animal

Now let’s use our Dog:

public class AnimalChorus{
    public static void sing(Animal a){
        system.debug(a.speak());
    }
}

//in Execute Anonymous
Dog poochy = new Dog();
AnimalChorus.sing(poochy);

//Debug output:
Bark!

The method sing in AnimalChorus accepts objects of the type Animal. Since Dog implements Animal, it is accepted as a parameter for the method sing. However, because sing accepts an Animal and not a Dog, it can only access Animal methods. Let’s add another method to our Dog.

public class Dog implements Animal{
    public String growl(){
        return 'grrrr';
    }
    public String speak(){
        return 'Bark!'
    }
}

If we try to use the growl method in AnimalChorus we’ll get an error.

public class AnimalChorus{
    public static void sing(Animal a){
        system.debug(a.growl());
        //This would not compile, throwing the error:
        //Method does not exist or incorrect signature: [Animal].growl()
    }
}

So you can think of an interface as a contract; an object is free to have its own unique logic as long as it implements the methods of the interface. This grants us flexibility when we write code. Let’s add some other animals to our chorus.

public class Bird implements Animal{
    public String speak(){
        return 'Tweet!'
    }
}

public class Cat implements Animal{
    public String speak(){
        return 'Meow!'
    }
}

public class Cow implements Animal{
    public String speak(){
        return 'Moo!'
    }
}

//in Execute Anonymous
Dog poochy = new Dog();
Bird tweety = new Bird();
Cat kitty = new Cat();
Cow moomoo = new Cow();

AnimalChorus.sing(poochy);
AnimalChorus.sing(tweety);
AnimalChorus.sing(kitty);
AnimalChorus.sing(moomoo);

//Debug output:
Bark!
Tweet!
Meow!
Moo!

By using an interface, the method sing is decoupled from its dependency on the animals. We could change how all the animals sing or add new animals, thus giving sing some flexibility in what it does without having to change it at all.

However, with all this flexibility, interfaces themselves are pretty inflexible. If we wanted to add another function to our interface, we have to update EVERY implementation of that interface with that function. It seems like a huge drawback, but in reality you probably won’t find it to be much of an issue. The biggest benefit I’ve found from interfaces comes with testing, which we’ll discuss in the next post!

Getting Sassy! Namespacing Bootstrap

Bootstrap is the most popular front-end web design framework and is usually my go to when I want to quickly create a user interface that is visually appealing and mobile friendly. I'll be the first to admit that I am not that great at design (just look at this blog!), so frameworks like Bootstrap are a godsend. Using Bootstrap with Salesforce (at least the classic view) can be a huge pain because of the conflicting stylesheets from the sidebar and header:

Conflicting Styles

This isn't the case in Salesforce Lightning, but there are plenty of organizations that are not ready for the transition to the new interface. I knew that the answer to this problem was just to namespace the Bootstrap, but the execution involved running commands with Ruby, Sass, and Node, which for a while was just non-Salesforce magic that I dared not touch. For a few years I just avoided using Bootstrap in Salesforce, opting to just style everything myself. If you've ever felt this way, then this post is the hand holding you might be looking for.

TL;DR

If you really don't want to do this, here's the namespaced CSS that you can just include in your project now: https://gist.github.com/seanpat09/6207236541d701da40ce

It doesn't include the glyphicon fonts, but pretty much everything else is there.

Namespacing Bootstrap

(This is mainly for Mac users. Linux will largely be the same. Sorry Windows users)

Run all these commands in Terminal

Install the dependencies on your machine

1. Make sure you have Ruby installed

Ruby comes pre-installed on Macs, but here's how you check for sure:

Your-Macintosh:~ seancuevo$ ruby -v
ruby 2.0.0p481 (2014-05-08 revision 45883) [universal.x86_64-darwin14]

If somehow you see something like this:

Your-Macintosh:~ seancuevo$ ruby -v
-bash: ruby: command not found

Then you need to install Ruby

2. Install Sass

gem install sass

If you see any errors, trying running this:

sudo gem install sass

3. Install nvm

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.30.1/install.sh | bash

4. Install node.js using nvm

nvm install 5.0

You can use node in your terminal session with:

nvm use 5.0

You now have all the tools necessary to namespace Bootstrap!

Compile a namespaced version of Bootstrap

You can run the following commands from whatever directory you want, but just make sure to stay in that directory as all the files will be written to the directory and all of the commands will be relative to it.

1. Start node:

nvm use 5.0

2. Install Bootstrap-sass

npm install bootstrap-sass

This creates a folder called node_modules in your current directory. This contains files necessary to compile bootstrap

3. Create the .scss file

In the same directory, create a file called sfdcBootstrap.scss with the following contents

.sfdcBootstrap{
$icon-font-path: "fonts/bootstrap/";
@import "node_modules/bootstrap-sass/assets/stylesheets/bootstrap";
}

This will create the bootstrap css file where only styles that descend from the .sfdcBootstrap class are affected by Bootstrap. You can name the class whatever you want, just make sure to change it in the .scss file.

4. Compile your css file with Sass

In the same directory, run this command in Terminal:

sass sfdcBootstrap.scss sfdcBootstrap.css

You should now have a file called sfdcBootstrap.css in your directory.

5. Build your static resource

Run this command to open your current directory in Finder:

open .
  • In Finder, create another folder and put the sfdcBootstrap.css in it.
  • In the node_modules folder, navigate to bootstrap-sass > assets.
  • Copy the fonts folder and place that in the same folder as sfdcBoostrap.css.
  • Select both sfdcBoostrap.css and the fonts folder, right click and select Compress 2 Items
  • Rename the resulting archive file to sfdcBootstrap and upload to Salesforce as a static resource.

Use your namespaced bootstrap in your Visual Force Page

Here is a sample Visual Force page using the resource:

<apex:page showHeader="true" sidebar="true">
<apex:stylesheet value="{!URLFOR($Resource.sfdcBootstrap, 'sfdcBootstrap.css')}" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<div class="sfdcBootstrap">
Formatted with bootstrap!
</div
Not formatted with bootstrap!
</apex:page>

Everything outside of the sfdcBootstrap div (which includes the sidebar and header) will NOT be formatted with Bootstrap

Namespaced Bootstrap

Git 'Er Done: Adding Git to Your Salesforce Development Process

Version control is a crucial component of any development process and even more so if you are working in a team. It is so important that I will refuse to work on any project before implementing some kind of version control system even if it means I have to maintain it on my own. Not only has it saved my ass countless times, it also facilitates and speeds up collaboration for development teams.

Git is my preferred version control system and after reading this post you will learn:

  • How to get your Salesforce code set up in Git
  • How to utilize version control in your development workflow

Getting your Salesforce code on to Git

If you don’t have Git set up on your machine, check out these two links first:

https://git-scm.com/book/en/v2/Getting-Started-Installing-Git

https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup

Next pull down the metadata that you want to track from your Salesforce production org using whichever method you prefer (Mavensmate, Eclipse, Ant, etc). We’re using pulling the code from production because it is the source of truth of your org. Even if your sandbox has new changes in it, it can be refreshed at any time or never merged into production. Production always takes precedent.

If you’re not sure which metadata types you should pull down, I recommend this package.xml file as a default:

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
<members>*</members>
<name>ApexClass</name>
</types>
<types>
<members>*</members>
<name>ApexComponent</name>
</types>
<types>
<members>*</members>
<name>ApexPage</name>
</types>
<types>
<members>*</members>
<name>ApexTrigger</name>
</types>
<types>
<members>*</members>
<name>StaticResource</name>
</types>
<version>34.0</version>
</Package>

Developers will be working with these metadata types for a majority of their time and thus these will benefit from version control the most.

Once you’ve pull down your metadata open up Terminal (or Git Bash if you’re using Windows) and navigate to the root folder of your project. This is typically the folder that holds your src folder. Run these commands to create your git repository:

//creates the repo
git init

//adds everything in the folder to the repo
git add .

//commits code to your repo. You can change the message to whatever you want,
//but this is what I usually put
git commit -m "current state of production code"

And you’re done! Adding your git repository to a remote location is out of scope for this blog post, but I suggest using one of the following:
BitBucket - Better for consultants because the pricing model is to pay per collaborator with unlimited private repositories
GitHub - Better for product developers or those working in industry as you pay per private repo with unlimited collaborators.

Adding Version Control to Your Development Workflow

Here’s a really basic development workflow for any new feature you are working on:

  1. Create a branch off of the master branch (typically named after the feature or story number)
  2. Make a change in the code that you can describe in one sentence without using the word “and” (e.g. ‘Stubbed out controller tests’)
  3. Commit the change to your branch
  4. Repeat steps 2 and 3 until the feature is completed (which includes testing)
  5. Merge into the master branch
  6. Deploy the master branch to your Production org.

Let’s break down each of these steps into more detail:

1. Create a branch off of the master branch (typically named after the feature or story number)

First, create or refresh a sandbox for you to develop in. You want your development org to mirror your production org as much as possible so that you know that the features you are building will integrate smoothly with what’s currently in production. In Terminal, create a branch off of the master branch with the following commands:

//Make sure you are actually in the master branch
git checkout master

//Create a new branch and put yourself in it at the same time. myBranch can be named whatever you want.
//I usually name it after the feature you are building, or use the story number if you're doing agile
git checkout -b myBranch

In your IDE, make sure you are saving files to your sandbox org, not production. You’re now ready to start developing!

2. Make a change in the code that you can describe in one sentence without using the word “and”

Commits should be small and descriptive. This makes tracking history, comparing file differences, and reverting code much easier. It’s easier to make sense of a bunch of small changes instead of one giant change. Also, if your history is a series of steps you have the flexibility of reverting only certain changes instead of all or nothing.

3. Commit the change to your branch

After you make a (small) change, do the following in Terminal: (I’ve included the outputs so you know what to expect)

//add the file(s) you changed to git. You can also do git add .
//but I prefer to be explicit
My-Computer:myProject thisIsMe$ git add src/classes/ContactController.cls

//View the changes you staged. Not necessary but I do it to make sure
//I only add what I expected to add
My-Computer:myProject thisIsMe$ git status
On branch newFeature
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

modified: src/classes/ContactController.cls

//Commit the change to Git
My-Computer:myProject thisIsMe$ git commit -m 'my change'
[newFeature bae2c2d] my change
1 file changed, 1 insertion(+), 1 deletion(-)

4. Repeat steps 2 and 3 until the feature is completed (which includes testing)

Continue to make small changes until you are ready to call the feature complete. This includes any unit testing you need to do as well as any QA/UAT.

5. Merge into the master branch

When you are done, it’s time to merge it to the master branch:

//Checkout the branch you are merging into
git checkout master

//Merge the branch with the feature you've been working on
git merge myChange

6. Deploy the master branch to your Production org.

Once it is merged into the master branch, go ahead and deploy the code to your production org using whichever method your prefer (your IDE, change set, ant).

Why create a new branch? Why not just work in master?

Working in branches gives you more flexibility and facilitates working on separate features simultaneously. Take the following example:

You are tasked with adding a new feature:

git checkout master
git checkout -b newFeature

While you are creating that new feature, the business says there’s a bug in production that needs to be fixed quickly. So you do the following:

//Get back into the master branch, which does not include any code from the new feature
git checkout master

//Create a new branch for your hot fix.
git checkout -b hotFix

Once you complete the hot fix and merge it into your master branch (and then production org), you can just return to work on your new feature as if nothing happened. You don’t have to manually remove or add code; Git did it all for you. If you want, you can also merge the hot fix into your newFeature branch so that your branch is caught up with master.

git checkout newFeature
git merge hotFix

New Possibilities

While version adds some overhead to development process, it also helps you become more productive. Having a history will make debugging issues easier as you’ll have a trail of what changed in the code when the bug arose. You’ll also feel more empowered to make changes in the code because if something goes wrong you always have something to revert back to.

Version control also opens the door to new opportunities. In the next post, we’ll cover how to use Git to automate deployments and manage collaboration between several developers.