Getting Started

The basic pattern for integrating Autofac into your application is:

  • Structure your app withinversion of control (IoC) in mind.

  • Add Autofac references.

  • At application startup…

    • Create aContainerBuilder.

    • Register components.

    • Build the container and store it for later use.

  • During application execution…

    • Create a lifetime scope from the container.

    • Use the lifetime scope to resolve instances of the components.

This getting started guide walks you through these steps for a simple console application. Once you have the basics down, you can check out the rest of the wiki for more advanced usage andintegration information for WCF, ASP.NET, and other application types.

Structuring the Application

The idea behind inversion of control is that, rather than tie the classes in your application together and let classes “new up” their dependencies, you switch it around so dependencies are instead passed in during class construction.Martin Fowler has an excellent article explaining dependency injection/inversion of control if you want more on that.

For our sample app, we’ll define a class that writes the current date out. However, we don’t want it tied to theConsole because we want to be able to test the class later or use it in a place where the console isn’t available.

We’ll also go as far as allowing the mechanism writing the date to be abstracted, so if we want to, later, swap in a version that writestomorrow’s date, it’ll be a snap.

We’ll do something like this:

usingSystem;namespaceDemoApp{// This interface helps decouple the concept of// "writing output" from the Console class. We// don't really "care" how the Write operation// happens, just that we can write.publicinterfaceIOutput{voidWrite(stringcontent);}// This implementation of the IOutput interface// is actually how we write to the Console. Technically// we could also implement IOutput to write to Debug// or Trace... or anywhere else.publicclassConsoleOutput:IOutput{publicvoidWrite(stringcontent){Console.WriteLine(content);}}// This interface decouples the notion of writing// a date from the actual mechanism that performs// the writing. Like with IOutput, the process// is abstracted behind an interface.publicinterfaceIDateWriter{voidWriteDate();}// This TodayWriter is where it all comes together.// Notice it takes a constructor parameter of type// IOutput - that lets the writer write to anywhere// based on the implementation. Further, it implements// WriteDate such that today's date is written out;// you could have one that writes in a different format// or a different date.publicclassTodayWriter:IDateWriter{privateIOutput_output;publicTodayWriter(IOutputoutput){this._output=output;}publicvoidWriteDate(){this._output.Write(DateTime.Today.ToShortDateString());}}}

Now that we have a reasonably structured (if contrived) set of dependencies, let’s get Autofac in the mix!

Add Autofac References

The first step is to add Autofac references to your project. For this example, we’re only using core Autofac.Other application types may use additional Autofac integration libraries..

The easiest way to do this is through NuGet. The “Autofac” package has all the core functionality you’ll need.

../_images/gs-nuget.png

Application Startup

At application startup, you need to create aContainerBuilder and register yourcomponents with it. Acomponent is an expression, .NET type, or other bit of code that exposes one or moreservices and can take in otherdependencies.

In simple terms, think about a .NET type that implements an interface, like this:

publicclassSomeType:IService{}

You could address that type in one of two ways:

  • As the type itself,SomeType

  • As the interface, anIService

In this case, thecomponent isSomeType and theservices it exposes areSomeType andIService.

In Autofac, you’d register that with aContainerBuilder something like this:

// Create your builder.varbuilder=newContainerBuilder();// Usually you're only interested in exposing the type// via its interface:builder.RegisterType<SomeType>().As<IService>();// However, if you want BOTH services (not as common)// you can say so:builder.RegisterType<SomeType>().AsSelf().As<IService>();

For our sample app, we need to register all of our components (classes) and expose their services (interfaces) so things can get wired up nicely.

We also need to store the container so it can be used to resolve types later.

usingSystem;usingAutofac;namespaceDemoApp{publicclassProgram{privatestaticIContainerContainer{get;set;}staticvoidMain(string[]args){varbuilder=newContainerBuilder();builder.RegisterType<ConsoleOutput>().As<IOutput>();builder.RegisterType<TodayWriter>().As<IDateWriter>();Container=builder.Build();// The WriteDate method is where we'll make use// of our dependency injection. We'll define that// in a bit.WriteDate();}}}

Now we have acontainer with all of thecomponents registered and they’re exposing the properservices. Let’s make use of it.

Application Execution

During application execution, you’ll need to make use of the components you registered. You do this byresolving them from alifetime scope.

The container itselfis a lifetime scope, and you can technically just resolve things right from the container.It is not recommended to resolve from the container directly, however.

When you resolve a component, depending on theinstance scope you define, a new instance of the object gets created. (Resolving a component is roughly equivalent to calling “new” to instantiate a class. That’s really, really oversimplifying it, but from an analogy perspective it’s fine.) Some components may need to be disposed (like they implementIDisposable) -Autofac can handle disposing those components for you when the lifetime scope is disposed.

However, the container lives for the lifetime of your application. If you resolve a lot of stuff directly from the container, you may end up with a lot of things hanging around waiting to be disposed. That’s not good (and you may see a “memory leak” doing that).

Instead, create achild lifetime scope from the container and resolve from that. When you’re done resolving components, dispose of the child scope and everything gets cleaned up for you.

(When you’re working with theAutofac integration libraries, this child scope creation is largely done for you so you don’t have to think about it.)

For our sample app, we’ll implement the “WriteDate” method to get the writer from a scope and dispose of the scope when we’re done.

namespaceDemoApp{publicclassProgram{privatestaticIContainerContainer{get;set;}staticvoidMain(string[]args){// ...the stuff you saw earlier...}publicstaticvoidWriteDate(){// Create the scope, resolve your IDateWriter,// use it, then dispose of the scope.using(varscope=Container.BeginLifetimeScope()){varwriter=scope.Resolve<IDateWriter>();writer.WriteDate();}}}}

Now when you run your program…

  • TheWriteDate method creates a lifetime scope from which it can resolve dependencies. It does this to avoid any memory leaks - ifIDateWriter or its dependencies are disposable, they will be automatically disposed when the scope is disposed.

  • TheWriteDate method manually resolves anIDateWriter from the lifetime scope. (This is “service location.”) Internally…

    • Autofac sees thatIDateWriter maps toTodayWriter so starts creating aTodayWriter.

    • Autofac sees that theTodayWriter needs anIOutput in its constructor. (This is “constructor injection.”)

    • Autofac sees thatIOutput maps toConsoleOutput so creates a newConsoleOutput instance.

    • Autofac uses the newConsoleOutput instance to finish constructing theTodayWriter.

    • Autofac returns the fully-constructedTodayWriter forWriteDate to consume.

  • The call towriter.WriteDate() goes to the brand newTodayWriter.WriteDate() since that’s what was resolved.

  • The Autofac lifetime scope is disposed. Any disposable items that were resolved from that lifetime scope are also disposed.

Later, if you want your application to write a different date, you could implement a differentIDateWriter and then change the registration at app startup. You don’t have to change any other classes. Yay, inversion of control!

Note: generally speaking, service location is largely considered an anti-pattern(see article). That is, manually creating scopes everywhere and sprinkling use of the container through your code is not necessarily the best way to go. Using theAutofac integration libraries you usually won’t have to do what we did in the sample app above. Instead, things get resolved from a central, “top level” location in the application and manual resolution is rare. Of course, how you design your app is up to you.

Going Further

The sample app gives you an idea of how to use Autofac, but there’s a lot more you can do.

Need Help?

Building from Source

The source code along with Visual Studio project files is availableon GitHub. Build instructions and details on contributing can be found in theContributor Guide.