// 用户服务接口
namespace WebApplication1.Interface{
public interface IUserService{
public string GetName();
}
}
// -------------------------------------
// 用户服务实现类
using WebApplication1.Interface;
namespace WebApplication1.Service{
public interface UserService: IUserService{
public string GetName(){
return "zhangsan";
}
}
}
准备好上面的接口和服务之后,就可以通过依赖注入方式去使用了:
//Program.cs
using WebApplication1.Interface;
using WebApplication1.Service;
//注册服务
builder.Services.AddScoped<IUserService, UserService>();
// 在路由终结点中通过方法注入使用
app.MapGet("/GetName",(IUserService user)=>
{
return user.GetName();
});
上面例子中虽然我可以直接 new UserService() 对象出来,但是这破坏了 开闭原则,我们应该依赖抽象(接口)而不是依赖具体的实现(对象);
IoC的 生命周期
在IOC容器中,常见的对象生命周期有以下:
1、瞬态(Transient):每次从Ioc容器请求获取对象时,都会创建一个新的实例。每个对象实例在使用后都会被销毁。这种生命周期适用于无状态的对象,不需要在多个地方共享或保留状态。
2、单例(Singleton):在整个应用程序中只会创建一个实例,并且每次从IoC容器请求获取对象时都会返回同一个实例。这意味着该对象会被重用,并且在整个应用程序生命周期内保持唯一。单例对象通常用于表示应用程序中的共享资源或全局服务。
3、作用域(Scoped):在每个作用域(例如HTTP请求)中创建一个实例,并且在同一个作用域内多次请求获取对象时都返回同一个实例。在不同的作用域中,将创建新的实例。这种生命周期适用于需要在特定作用域内共享对象实例的情况,比如Web应用程序中的每个HTTP请求。
//builder.Services.AddTransient<IUserService,UserService>();
//builder.Services.Addsingleton<IUserService,UserService>();
//builder.Services.AddScoped<IUserService,UserService>();
这些生命周期的区别主要在于:对象实例的创建和销毁方式,以及对象的重用性。
- 瞬态 创建和销毁对象的开销较大,适用于无状态对象;
- 单例 减少了对象的创建和销毁开销,并且提供全局唯一的对象实例;
- 作用域 适用于需要在特定作用域内共享对象的情况,可以在不同作用域之间创建不同的对象实例。
需要注意的是,不同的IoC容器实现可能对生命周期的实现方式有所不同。以上是一股情况下的常见生命周期,具体实现可以根据不同的IOC容器和框架进行调整和配置。
注入方式
在IoC容器中,注入方式有以下几种:
1、构造函数注入(Constructor Injection):通过类的构造函数来注入依赖项。在创建类的实例时,依赖项作为构造函数的参数进行传递。这是 最常用的注入方式之一,能够确保依赖项在对象创建时被传入,并且在整个对象生命周期中保持不变。
2、属性注入(Property Injection):通过类的 公共属性 来注入依赖项。依赖项通过属性的Setter方法进行注入。在对象创建后,IOC容器会自动设暨相应的属性值。相比构造函数注入,属性注入更加灵活,可以在对象创建后动态地注入依赖项。
3、方法注入(Method Injection):通过类的 公共方法 来注入依赖项。依赖项作为方法的参数进行传递。在对象创建后,IOC容器会调用相应的方法,并传入依赖项。方法注入通常在对象创建后需要进行一些特定的初始化操作时使用。
这些注入方式可以单独使用,也可以组合使用,根据具体的需求和依赖关系来选择适当的方式。注入方式的选择也取决于使用的IOC容器和框架,不同的容器可能对注入方式有所不同。
注意:内置的DI依赖注入只支持构造函数注入,如果想支持属性或方法的注入,请使用第三方依赖注入比如 Autofac 去注入