diff --git a/app.go b/app.go
index 34205290a..106603279 100644
--- a/app.go
+++ b/app.go
@@ -5,25 +5,30 @@ import (
 	"os"
 	"path/filepath"
 	"strings"
+	"time"
 
+	"github.com/cloudsonic/sonic-server/conf"
+	"github.com/cloudsonic/sonic-server/scanner"
 	"github.com/go-chi/chi"
-	chimiddleware "github.com/go-chi/chi/middleware"
+	"github.com/go-chi/chi/middleware"
 	"github.com/sirupsen/logrus"
 )
 
 type App struct {
-	router *chi.Mux
-	logger *logrus.Logger
+	router   *chi.Mux
+	logger   *logrus.Logger
+	importer *scanner.Importer
 }
 
 func (a *App) Initialize() {
 	a.logger = logrus.New()
 	a.initRoutes()
+	a.initImporter()
 }
 
 func (a *App) MountRouter(path string, subRouter http.Handler) {
 	a.router.Group(func(r chi.Router) {
-		r.Use(chimiddleware.Logger)
+		r.Use(middleware.Logger)
 		r.Mount(path, subRouter)
 	})
 }
@@ -36,10 +41,10 @@ func (a *App) Run(addr string) {
 func (a *App) initRoutes() {
 	r := chi.NewRouter()
 
-	r.Use(chimiddleware.RequestID)
-	r.Use(chimiddleware.RealIP)
-	r.Use(chimiddleware.Recoverer)
-	r.Use(chimiddleware.Heartbeat("/ping"))
+	r.Use(middleware.RequestID)
+	r.Use(middleware.RealIP)
+	r.Use(middleware.Recoverer)
+	r.Use(middleware.Heartbeat("/ping"))
 
 	r.Get("/", func(w http.ResponseWriter, r *http.Request) {
 		http.Redirect(w, r, "/static/Jamstash", 302)
@@ -51,6 +56,20 @@ func (a *App) initRoutes() {
 	a.router = r
 }
 
+func (a *App) initImporter() {
+	a.importer = initImporter(conf.Sonic.MusicFolder)
+	go a.startPeriodicScans()
+}
+
+func (a *App) startPeriodicScans() {
+	for {
+		select {
+		case <-time.After(5 * time.Second):
+			a.importer.CheckForUpdates(false)
+		}
+	}
+}
+
 func FileServer(r chi.Router, path string, root http.FileSystem) {
 	if strings.ContainsAny(path, "{}*") {
 		panic("FileServer does not permit URL parameters.")
diff --git a/controllers/sync.go b/controllers/sync.go
deleted file mode 100644
index 2c7117a0a..000000000
--- a/controllers/sync.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package controllers
-
-import (
-	"github.com/astaxie/beego"
-	"github.com/cloudsonic/sonic-server/scanner"
-)
-
-type SyncController struct{ beego.Controller }
-
-func (c *SyncController) Get() {
-	scanner.CheckForUpdates(true)
-	c.Ctx.WriteString("Import started. Check logs")
-}
diff --git a/main.go b/main.go
index ae6b35963..54500439b 100644
--- a/main.go
+++ b/main.go
@@ -7,7 +7,6 @@ import (
 	"github.com/cloudsonic/sonic-server/api"
 	"github.com/cloudsonic/sonic-server/conf"
 	_ "github.com/cloudsonic/sonic-server/init"
-	_ "github.com/cloudsonic/sonic-server/tasks"
 )
 
 func main() {
diff --git a/scanner/importer.go b/scanner/importer.go
index 23280a917..cb1ca5dfb 100644
--- a/scanner/importer.go
+++ b/scanner/importer.go
@@ -24,55 +24,6 @@ type Scanner interface {
 
 type tempIndex map[string]domain.ArtistInfo
 
-var (
-	inProgress    chan int
-	lastCheck     time.Time
-	itunesLibrary string
-)
-
-func init() {
-	inProgress = make(chan int)
-	go func() {
-		time.Sleep(5 * time.Second)
-		startImport()
-	}()
-}
-
-func CheckForUpdates(force bool) {
-	<-inProgress
-
-	if force {
-		lastCheck = time.Time{}
-	}
-
-	startImport()
-}
-
-func startImport() {
-	go func() {
-		itunesLibrary = conf.Sonic.MusicFolder
-
-		info, err := os.Stat(itunesLibrary)
-		if err != nil {
-			inProgress <- 1
-			beego.Error(err)
-			return
-		}
-		if lastCheck.After(info.ModTime()) {
-			inProgress <- 1
-			return
-		}
-		lastCheck = time.Now()
-
-		// TODO Move all to DI
-		i := &Importer{mediaFolder: itunesLibrary}
-		utils.ResolveDependencies(&i.mfRepo, &i.albumRepo, &i.artistRepo, &i.idxRepo, &i.plsRepo,
-			&i.propertyRepo, &i.search, &i.scanner)
-		i.Run()
-		inProgress <- 1
-	}()
-}
-
 type Importer struct {
 	scanner      Scanner
 	mediaFolder  string
@@ -84,9 +35,48 @@ type Importer struct {
 	propertyRepo engine.PropertyRepository
 	search       engine.Search
 	lastScan     time.Time
+	lastCheck    time.Time
 }
 
-func (i *Importer) Run() {
+func NewImporter(mediaFolder string, scanner Scanner, mfRepo domain.MediaFileRepository, albumRepo domain.AlbumRepository, artistRepo domain.ArtistRepository, idxRepo domain.ArtistIndexRepository, plsRepo domain.PlaylistRepository, propertyRepo engine.PropertyRepository, search engine.Search) *Importer {
+	return &Importer{
+		scanner:      scanner,
+		mediaFolder:  mediaFolder,
+		mfRepo:       mfRepo,
+		albumRepo:    albumRepo,
+		artistRepo:   artistRepo,
+		idxRepo:      idxRepo,
+		plsRepo:      plsRepo,
+		propertyRepo: propertyRepo,
+		search:       search,
+	}
+}
+
+func (i *Importer) CheckForUpdates(force bool) {
+	if force {
+		i.lastCheck = time.Time{}
+	}
+
+	i.startImport()
+}
+
+func (i *Importer) startImport() {
+	go func() {
+		info, err := os.Stat(i.mediaFolder)
+		if err != nil {
+			beego.Error(err)
+			return
+		}
+		if i.lastCheck.After(info.ModTime()) {
+			return
+		}
+		i.lastCheck = time.Now()
+
+		i.scan()
+	}()
+}
+
+func (i *Importer) scan() {
 	i.lastScan = i.lastModifiedSince()
 
 	if i.lastScan.IsZero() {
diff --git a/scanner/wire_providers.go b/scanner/wire_providers.go
new file mode 100644
index 000000000..f63e77eb0
--- /dev/null
+++ b/scanner/wire_providers.go
@@ -0,0 +1,9 @@
+package scanner
+
+import "github.com/google/wire"
+
+var Set = wire.NewSet(
+	NewImporter,
+	NewItunesScanner,
+	wire.Bind(new(Scanner), new(*ItunesScanner)),
+)
diff --git a/tasks/scan.go b/tasks/scan.go
deleted file mode 100644
index 24e3d9b48..000000000
--- a/tasks/scan.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package tasks
-
-import (
-	"time"
-
-	"github.com/astaxie/beego"
-	"github.com/astaxie/beego/toolbox"
-	"github.com/cloudsonic/sonic-server/scanner"
-)
-
-const TaskItunesScan = "iTunes Library Scanner"
-
-func init() {
-	scan := toolbox.NewTask(TaskItunesScan, "0/5 * * * * *", func() error {
-		scanner.CheckForUpdates(false)
-		return nil
-	})
-
-	toolbox.AddTask(TaskItunesScan, scan)
-	go func() {
-		time.Sleep(20 * time.Second)
-		beego.Debug("Starting", TaskItunesScan)
-		toolbox.StartTask()
-	}()
-}
diff --git a/wire_gen.go b/wire_gen.go
new file mode 100644
index 000000000..d204b9dd7
--- /dev/null
+++ b/wire_gen.go
@@ -0,0 +1,45 @@
+// Code generated by Wire. DO NOT EDIT.
+
+//go:generate wire
+//+build !wireinject
+
+package main
+
+import (
+	"github.com/cloudsonic/sonic-server/engine"
+	"github.com/cloudsonic/sonic-server/itunesbridge"
+	"github.com/cloudsonic/sonic-server/persistence"
+	"github.com/cloudsonic/sonic-server/scanner"
+	"github.com/deluan/gomate"
+	"github.com/deluan/gomate/ledis"
+	"github.com/google/wire"
+)
+
+import (
+	_ "github.com/cloudsonic/sonic-server/init"
+)
+
+// Injectors from wire_injectors.go:
+
+func initImporter(musicFolder string) *scanner.Importer {
+	checkSumRepository := persistence.NewCheckSumRepository()
+	itunesScanner := scanner.NewItunesScanner(checkSumRepository)
+	mediaFileRepository := persistence.NewMediaFileRepository()
+	albumRepository := persistence.NewAlbumRepository()
+	artistRepository := persistence.NewArtistRepository()
+	artistIndexRepository := persistence.NewArtistIndexRepository()
+	playlistRepository := persistence.NewPlaylistRepository()
+	propertyRepository := persistence.NewPropertyRepository()
+	db := newDB()
+	search := engine.NewSearch(artistRepository, albumRepository, mediaFileRepository, db)
+	importer := scanner.NewImporter(musicFolder, itunesScanner, mediaFileRepository, albumRepository, artistRepository, artistIndexRepository, playlistRepository, propertyRepository, search)
+	return importer
+}
+
+// wire_injectors.go:
+
+var allProviders = wire.NewSet(itunesbridge.NewItunesControl, persistence.Set, engine.Set, scanner.Set, newDB)
+
+func newDB() gomate.DB {
+	return ledis.NewEmbeddedDB(persistence.Db())
+}
diff --git a/wire_injectors.go b/wire_injectors.go
new file mode 100644
index 000000000..1b999fa1e
--- /dev/null
+++ b/wire_injectors.go
@@ -0,0 +1,29 @@
+//+build wireinject
+
+package main
+
+import (
+	"github.com/cloudsonic/sonic-server/engine"
+	"github.com/cloudsonic/sonic-server/itunesbridge"
+	"github.com/cloudsonic/sonic-server/persistence"
+	"github.com/cloudsonic/sonic-server/scanner"
+	"github.com/deluan/gomate"
+	"github.com/deluan/gomate/ledis"
+	"github.com/google/wire"
+)
+
+var allProviders = wire.NewSet(
+	itunesbridge.NewItunesControl,
+	persistence.Set,
+	engine.Set,
+	scanner.Set,
+	newDB,
+)
+
+func initImporter(musicFolder string) *scanner.Importer {
+	panic(wire.Build(allProviders))
+}
+
+func newDB() gomate.DB {
+	return ledis.NewEmbeddedDB(persistence.Db())
+}