Autofac

Autofac (MVC Example)

Uses an IOC (Inversion of control) container, its simple to setup in an MVC application.

Install Autofac 5.2.0 and Autofac.Extensions.DependencyInjection 6.0.0

Startup.cs

The install should add ConfigureContainer to your Startup.cs, you dont need to build the container, you only nee to register things in it.

1
2
3
4
5
6
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterModule(new FooModule());
builder.RegisterModule(new BarModule());
builder.RegisterModule(new DataModule());
}

Modules

Modules are a cool way to group things in a cohesive manner.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
using System.Linq;
using Autofac;

namespace fooapp.Plumbing.IoC
{
public class ModuleData : Module
{
protected override void Load(ContainerBuilder builder)
{
// register things using the builder
}
}
}

Register things using the builder

You can then use the power of reflection in the DataModule class above to resolve things from a repository, this is cool as it will resolve things like ICoolRepository to CoolRepository because they have the string Repository in their names.

Its pretty common to do this for a Factory too.

1
2
3
4
builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetAssembly(typeof(SomeBaseClass)))
.Where(t => t.Name.EndsWith("Repository") || t.Name.EndsWith("Factory"))
.AsImplementedInterfaces()
.SingleInstance();

You can also look to the namespace when using reflection:

1
2
3
4
builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetAssembly(typeof(SomeBaseClass)))
.Where(t => t.IsInNamespace("fooapp.sweet.namespace"))
.AsImplementedInterfaces()
.SingleInstance();

Else if its a once off helper/magic just resolve directly

1
builder.RegisterInstance(new FooHelper()).As<IFooHelper>().SingleInstance();

SingleInstance

Called in the fluent api examples above with .SingleInstance();, remember not have any state in anything that expects to exist as a singleton.

Configure the component so that every dependent component or call to Resolve()

Autofac (Webforms Example)

Uses an IOC (Inversion of control) container. This was useful in a legacy Web Forms application (Autofac, Version=4.8.1.0) however it would have worked just as well in the MVC application I used Unity in.

install Autofac 4.9.1 and Autofac.Web 4.0.0

Update web.config to include this below system.webServer

1
2
3
4
5
6
7
8
9
10
<modules>
<add
name="ContainerDisposal"
type="Autofac.Integration.Web.ContainerDisposalModule, Autofac.Integration.Web"
preCondition="managedHandler"/>
<add
name="PropertyInjection"
type="Autofac.Integration.Web.Forms.PropertyInjectionModule, Autofac.Integration.Web"
preCondition="managedHandler"/>
</modules>

Add Global.asax if it doesn’t already exist, implement IContainerProviderAccessor

1
public class Global : System.Web.HttpApplication, IContainerProviderAccessor

Add some crap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Provider that holds the application container.
static IContainerProvider _containerProvider;

// Instance property that will be used by Autofac HttpModules
// to resolve and inject dependencies.
public IContainerProvider ContainerProvider
{
get { return _containerProvider; }
}

protected void Application_Start(object sender, EventArgs e)
{
// Build up your application container and register your dependencies.
var builder = new ContainerBuilder();
var connectionString = Tools.GetConnectionString("conn");

// Your DI :D
builder.Register(c => new MaterialRepository(connectionString))
.As<IMaterialRepository>();

// Once you're done registering things, set the container
// provider up with your registrations.
_containerProvider = new ContainerProvider(builder.Build());
}

In your page code behind

1
2
3
4
5
namespace MyNameSpace
{
public partial class SomePage : System.Web.UI.Page
{
public ISomeRepository _someRepository { get; set; }

Contextual Binding (Keyed Services)

This is the same as Ninjects Contextual Binding but uses .Keyed

Create an enum, for reasons :)

1
2
3
4
5
public enum LaunchDarklyProjectEnum
{
ProjectOne,
ProjectTwo
}

IoC Module example:

1
2
3
4
5
var sdkKeyProjectOne = "sdk-0000000000000000";

builder.Register(c => new LdClient(sdkKeyProjectOne))
.Keyed<ILdClient>(LaunchDarklyProjectEnum.ProjectOne)
.SingleInstance();

Resolve with KeyFilter

1
2
3
4
5
6
7
8
9
public class LdFeatureRepository {
private readonly ILdClient _ldClientProjectOne;

public LdFeatureRepository(
[KeyFilter(LaunchDarklyProjectEnum.ProjectOne)] ILdClient ldClientProjectOne)
{
_ldClientProjectOne = ldClientProjectOne;
}
}

Disposal

References