概述
.NetCore 或者 Asp.netCore 内置DI框架的特点:
1.不支持程序集注册:每增加一个服务,则需要一行代码进行注册。
2.不支持属性注入:内置DI只支持构造函数注入,不支持属性注入(当然,构造函数注入为主流)。
第三方DI框架Aufofac,很好的解决了上面的两个问题。当然,内置的DI,是使用第三方DI的基础,即第三方DI,是离不开内置DI的。
一、.NetCore 使用 AutoFac
第一步:添加Autofac
从nuget 添加的程序集中可以看出,不仅添加了 Autofac,还添加了.NetCore内置DI。因为内置DI是第三方DI的基石,如果不添加内置DI,后面代码就会报错。
第二步:Coding
接口定义:
public interface IAccount { }
public interface ITool { }
public interface IMessage { }
public interface ITest1 { }
Class定义:
public class Base
{
public Base()
{
Console.WriteLine($"Created:{GetType().Name}");
}
}
public class Account : Base,IAccount{ }
public class Tool : Base, ITool { }
public class Message : Base,IMessage { }
主体程序:
public class AutoFacAsembly
{
public static void run()
{
//Autofac 的DI容器构建对象
var containerBuilder = new ContainerBuilder();
//程序集注册
containerBuilder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
//筛选基类为Base
.Where(t => t.BaseType == typeof(Base))
//暴露第一节接口。通过第一个接口,就可以从aufac注册容器中,获取到实例对象
.As(t => t.GetInterfaces()[0])
//设置 生命周期 为Scope模式
.InstancePerLifetimeScope()
.PropertiesAutowired();//这一行,标识可以通过属性注入
//创建 autofac 容器,可从容器中,通过 抽象接口获取到 实例
var container = containerBuilder.Build();
IServiceProvider provider = new AutofacServiceProvider(container);
//通过 provider 来获取实例
Debug.Assert(provider.GetService<IAccount>() is Account);
Debug.Assert(provider.GetService<ITool>() is Tool);
//这里 message 是通过属性注入的(也可以改为构造函数注入)
var test = provider.GetService<ITest1>() as Test1;
Debug.Assert(provider.GetService<IMessage>() is Message);
Console.Read();
}
}
Program 类调用:
class Program
{
static void Main(string[] args)
{
AutoFacAsembly.run();
}
}
二、Asp.netCore 使用AutoFac
第一步:添加Autofac
Asp.netCore 应用程序已经在Startup 类中添加了自带DI框架,因此不再自行引用。只需nuget 添加Autofac即可。
第二步:coding
接口和类定义:
namespace WebApplication1.Services
{
public interface IAccount { }
public interface IMessage
{
public string Text { get; set; }
}
public interface ITool { }
public class Account : IAccount { }
public class Message : IMessage
{
public string Text { get; set; }
public Message()
{
Text = "Hello Message";
}
}
public class Tool : ITool { }
}
Startup类中添加方法:
/// <summary>
/// 这个方法由asp.netcore 运行时框架自动调用,且框架会注入ContainerBuilder
/// </summary>
/// <param name="builder">ContainerBuilder 是Autofac的容器构建对象</param>
public void ConfigureContainer(ContainerBuilder builder)
{
var assembly = Assembly.GetExecutingAssembly();
// 程序集注册
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
// 筛选命名空间为 Services
.Where(t => t.Namespace == assembly.GetName().Name + ".Services")
// 暴露注册类型的接口,这里暴露的是所有的接口
.AsImplementedInterfaces()
//.As(t=>t.GetInterfaces()[0]) //暴露的是第一个接口
//.AsSelf() //暴露自己,说明是一个单一类型,没有实现任何接口
// 生命周期模式为Scope
.InstancePerLifetimeScope();
}
Program 类:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
//Aufofac是第三方的DI,如果想要asp.netcore 运行时自动调用 startup类中的 ConfigureContainer,
//就要添加AutofacServiceProviderFactory
.UseServiceProviderFactory(new AutofacServiceProviderFactory());
}
控制器代码:
namespace WebApplication1.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class MessageController : ControllerBase
{
private readonly IMessage _message;
/// <summary>
/// _message 通过构造函数注入。Controller是asp.netcore 框架自动调用的,不需要我们去创建controller对象
/// </summary>
/// <param name="message"></param>
public MessageController(IMessage message)
{
_message = message;
}
public IActionResult Get()
{
return Ok(_message.Text);
}
}
}