1、前言
前面的博客已经介绍过ASP.NET Core中内置IoC容器的使用方法。对于规模较小的项目来说,内置容器完全够用。但在实际开发业务中,一般更推荐开发者使用Autofac作为系统的IoC容器。相较于微软提供的内置容器,Autofac无论是在功能性还是灵活性上都更胜一筹,下面开始介绍它的使用方法。
2、创建接口和类
本文通过控制台程序进行演示。使用NuGet引入如下组件:
Autofac

创建一个IAnimal接口,代码如下:
namespace App
{
public interface IAnimal
{
string GetMsg();
}
}
创建Cat类实现IAnimal接口,代码如下:
namespace App
{
public class Cat : IAnimal
{
public string GetMsg()
{
return "This is cat";
}
}
}
创建Dog类实现IAnimal接口,代码如下:
namespace App
{
public class Dog : IAnimal
{
public string GetMsg()
{
return "This is dog";
}
}
}
3、Autofac基本注册方法
Autofac中包含两个关键类:ContainerBuilder和IContainer。其中ContainerBuilder是一个规则构建器,主要负责类和接口的注册。IContainer相当于容器,主要通过Resolve方法提供开发者需要的对象实例。它们的实例化方式如下所示:
using Autofac;
namespace App
{
internal class Program
{
static void Main(string[] args)
{
ContainerBuilder builder = new ContainerBuilder();
IContainer container = builder.Build();
}
}
}
3.1、Register注册
Autofac中的Register方法可对类和接口进行注册,下面就来注册一下IAnimal接口和Cat类,代码如下:
using Autofac;
using System;
namespace App
{
internal class Program
{
static void Main(string[] args)
{
// 注册接口和类
ContainerBuilder builder = new ContainerBuilder();
builder.Register(p => new Cat()).As<IAnimal>();
// 构建容器
IContainer container = builder.Build();
// 创建IAnimal实例
IAnimal animal = container.Resolve<IAnimal>();
Console.WriteLine(animal.GetMsg());
}
}
}
运行结果如下所示:
This is cat
3.2、RegisterType注册
Autofac中也可以使用RegisterType方法注册类接口和类,代码如下:
using Autofac;
using System;
namespace App
{
internal class Program
{
static void Main(string[] args)
{
// 注册接口和类
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<Cat>().As<IAnimal>();
// 构建容器
IContainer container = builder.Build();
// 创建IAnimal实例
IAnimal animal = container.Resolve<IAnimal>();
Console.WriteLine(animal.GetMsg());
}
}
}
运行结果如下所示:
This is cat
3.3、RegisterInstance注册
Autofac提供了一个RegisterInstance方法,该方法支持实例注册,代码如下:
using Autofac;
using System;
namespace App
{
internal class Program
{
static void Main(string[] args)
{
// 注册接口和类
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterInstance(new Cat()).As<IAnimal>();
// 构建容器
IContainer container = builder.Build();
// 创建IAnimal实例
IAnimal animal = container.Resolve<IAnimal>();
Console.WriteLine(animal.GetMsg());
}
}
}
运行结果如下所示:
This is cat
4、实例被覆盖的解决方法
一个接口可以有多个类来实现它。在上面的代码中,Cat和Dog均实现了IAnimal接口。如果在Autofac中同时注册这两个类,则会引发实例覆盖问题,代码如下:
using Autofac;
using System;
namespace App
{
internal class Program
{
static void Main(string[] args)
{
// 注册接口和类
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<Cat>().As<IAnimal>();
builder.RegisterType<Dog>().As<IAnimal>();
// 构建容器
IContainer container = builder.Build();
// 创建IAnimal实例
IAnimal animal = container.Resolve<IAnimal>();
Console.WriteLine(animal.GetMsg());
}
}
}
运行结果如下所示:
This is dog
在上面的代码中,我们先注册了Cat,然后注册了Dog,此时Dog的实例就会覆盖Cat的实例。如果希望同时获取这两个类的实例,则可以使用Named和ResolveNamed方法,代码如下:
using Autofac;
using System;
namespace App
{
internal class Program
{
static void Main(string[] args)
{
// 注册接口和类
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<Cat>().Named<IAnimal>("Cat");
builder.RegisterType<Dog>().Named<IAnimal>("Dog");
// 构建容器
IContainer container = builder.Build();
// 创建Cat实例
IAnimal cat = container.ResolveNamed<IAnimal>("Cat");
Console.WriteLine(cat.GetMsg());
// 创建Dog实例
IAnimal dog = container.ResolveNamed<IAnimal>("Dog");
Console.WriteLine(dog.GetMsg());
}
}
}
运行结果如下所示:
This is cat
This is dog
5、Autofac模块的单独配置
在实际开发业务中,为了方便代码的管理,我们一般会单独建一个类来管理Autofac的模块。新建一个类IocModule,该类继承Autofac.Module,代码如下:
using Autofac;
namespace App
{
public class IocModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<Cat>().Named<IAnimal>("Cat");
builder.RegisterType<Dog>().Named<IAnimal>("Dog");
}
}
}
上面的代码重写了Load方法,我们可以在该方法中注册接口和类,最后在容器中加载IocModule 即可,代码如下:
using Autofac;
using System;
namespace App
{
internal class Program
{
static void Main(string[] args)
{
// 注册接口和类
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterModule(new IocModule());
// 构建容器
IContainer container = builder.Build();
// 创建Cat实例
IAnimal cat = container.ResolveNamed<IAnimal>("Cat");
Console.WriteLine(cat.GetMsg());
// 创建Dog实例
IAnimal dog = container.ResolveNamed<IAnimal>("Dog");
Console.WriteLine(dog.GetMsg());
}
}
}
运行结果如下所示:
This is cat
This is dog
6、结语
本文主要介绍了Autofac的基础使用方法。其实Autofac中还包含一些高效灵活的注册方法,例如程序集批量注册、泛型注册等等,合理使用这些方法能够极大地提升开发效率,后续博客会对这些方法进行逐一介绍。



















