title: How to achieve component scanning/auto discovery of Controllers using Inversify + inversify-express-utils
body: <p>I am looking for a way to load my controller classes in Inversify that are annotated with <code>@controller()</code> from <code>inversify-express-utils</code> without needing to manage a hand crafted/manually constructed module of imports/exports.</p>
  
  <p>All of the examples I am seeing seem to indicate that in your entry file you need to import each of your controllers explicitely so that <code>inversify-express-utils</code> picks up on the <code>@controller</code> annotations, however this feels like it would be rather tedious for applications of a medium to large size.</p>
  
  <p>In plain JavaScript I would do something like recursively require each file in a directory at runtime, however I understand that due to the way TypeScript works, this isn't exactly possible?</p>
  
  <p>Using the <code>inversify-binding-decorators</code> package, I am able to simply annotate a service with <code>@provide()</code> and that seems to be enough to have the class added to the IOC container, however that does not seem to be enough for <code>inversify-express-utils</code> to discover the <code>@controller()</code> annotations on the class.</p>
  
  <p>Is there a way to achieve auto discovery of these <code>@controller()</code> annotated classes without manually importing them into a entry file? </p>
  
  <p><strong>/services/StarwarsNamesService.ts</strong></p>
  
  <pre><code>import { provide } from 'inversify-binding-decorators';
  import * as names from 'starwars-names';
  import * as matchSorter from 'match-sorter';
  
  @provide(StarwarsNamesService)
  export default class StarwarsNamesService {
  
      public getNames(): Array&lt;string&gt; {
          return names.all;
      }
  
      public getRandomNames(count?: number): Array&lt;string&gt; {
          if (!count) { count = 1; }
          return names.random(count);
      }
  
      public searchNames(term?: string): Array&lt;string&gt; {
          return matchSorter(this.getNames(), term);
      }
  }
  </code></pre>
  
  <p><strong>/controllers/StarWarsNamesController.ts</strong></p>
  
  <pre><code>import { inject } from 'inversify';
  import { controller, httpGet } from 'inversify-express-utils';
  import StarwarsNamesService from '../../starwars-names/StarwarsNamesService';
  
  @controller('/api/starwars-names')
  export default class StarWarsNamesController {
  
      @inject(StarwarsNamesService)
      private starwarsNamesService: StarwarsNamesService;
  
      @httpGet('/')
      public getAll(): any {
          return this.starwarsNamesService.getNames();
      }
  }
  </code></pre>
  
  <p><strong>boostrap.ts</strong></p>
  
  <pre><code>import 'reflect-metadata';
  import * as express from "express";
  import * as path from 'path';
  import { InversifyExpressServer } from 'inversify-express-utils';
  import { buildProviderModule } from "inversify-binding-decorators";
  import { Container } from 'inversify';
  
  // Has to be explicitly imported otherwise is undiscovered
  import './controllers/StarwarsNamesController.ts';
  
  let container = new Container();
  
  container.load(buildProviderModule());
  
  let server = new InversifyExpressServer(container);
  
  let serverInstance = server.build();
  
  serverInstance.listen(3000, () =&gt; {
      console.log('Server started on port 3000 :)');
  });
  </code></pre>
  
  <p><strong>Thrown Error:</strong></p>
  
  <pre><code>E:\..\..\node_modules\inversify-express-utils\lib\utils.js:10
          throw new Error(constants_1.NO_CONTROLLERS_FOUND);
                ^
  Error: No controllers have been found! Please ensure that you have register at least one Controller.
      at Object.getControllersFromContainer
      ...
  </code></pre>