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
中还包含一些高效灵活的注册方法,例如程序集批量注册、泛型注册等等,合理使用这些方法能够极大地提升开发效率,后续博客会对这些方法进行逐一介绍。