专业编程基础技术教程

网站首页 > 基础教程 正文

C# 依赖注入浅析(三) c#依赖注入和控制反转

ccvgpt 2024-12-28 11:47:29 基础教程 2 ℃

在.NET Core中,常见的依赖注入方式有:

1.构造函数注入(Constructor Injection):通过构造函数将依赖项注入到类中。

C# 依赖注入浅析(三) c#依赖注入和控制反转

构造函数注入是 .NET Core 中最推荐的依赖注入方式,因为它使类在使用时具有明确声明的依赖关系,并且可以确保所有必需的依赖项都已准备好。在构造函数中注入依赖项时,我们可以在每个类中设置依赖项,以便更清晰地了解它们的作用。通常情况下,构造函数注入适用于必需的依赖项,例如数据库上下文、配置参数等。

public class FooService : IFooService
{
    private readonly IBarService _barService;

    public FooService(IBarService barService)
    {
        _barService = barService;
    }

    // other methods...
}

public class BarService : IBarService
{
    // implementation...
}

2.属性注入(Property Injection):通过属性来注入依赖项,需要在类中定义一个公共的属性,并用 [Inject] 特性标注。

属性注入适用于可选的依赖项,例如日志记录器或散列服务等。属性注入要求在属性上设置 public setter,这会导致更多的代码要被执行,可能会导致唯一实例的违反单例模式。所以应该避免在属性上设置编写 setter。

public class FooService : IFooService
{
    [Inject]
    public IBarService BarService { get; set; }

    // other methods...
}

public class BarService : IBarService
{
    // implementation...
}

3.方法注入(Method Injection):通过方法将依赖项注入到类中。

方法注入通常用于需要依赖项访问的情况下。方法注入不太常用,但某些时候我们必须在方法中访问某些依赖项。此时,我们可以使用 [FromServices] 特性将依赖项注入方法参数。方法注入适用于需要在方法中临时访问依赖项的情况。

public class FooService : IFooService
{
    private IBarService _barService;

    [Inject]
    public void SetBarService(IBarService barService)
    {
        _barService = barService;
    }

    // other methods...
}

public class BarService : IBarService
{
    // implementation...
}

需要注意的是,以上三种方式需要在启动应用程序时通过依赖注入容器进行注册,可以在 Startup.cs 文件中使用 IServiceCollection 来注册依赖项,然后通过 DI 容器获取它们的实例。例如:

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IFooService, FooService>();
		services.AddScoped<IBarService, BarService>();
}

4.服务定位器(Service Locator):通过一个静态类(通常称为ServiceLocator)来访问依赖项。

public class FooService : IFooService
{
    private readonly IServiceProvider _serviceProvider;

    public FooService(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public void DoSomething()
    {
        var barService = _serviceProvider.GetService<IBarService>();
        // use barService...
    }
}

public class BarService : IBarService
{
    // implementation...
}

需要注意的是,使用服务定位的方式虽然方便,但容易导致代码的耦合性提高,同时也不容易进行测试和维护。

5.手动注入:在某些场景下,需要手动创建依赖项并注入到实例中。

public class FooService : IFooService
{
    private readonly IBarService _barService;

    public FooService()
    {
        _barService = new BarService();
    }

    // other methods...
}

public class BarService : IBarService
{
    // implementation...
}

需要注意的是,手动注入容易导致代码的可扩展性不好,因为如果需要替换依赖项,就需要修改源代码,而不是通过配置或者更改依赖注入容器。

以上是.NET Core中依赖注入的几种方式,需要根据具体场景来选择最适合的方式。需要注意的是,在任何时候都应避免使用服务定位器或服务定位器模式,通过这种方式访问服务将导致代码的松散耦合性降低,导致代码变得难以测试和维护。最好的方式是通过构造函数注入、属性注入或方法注入将依赖项直接注入到类中。

创作不易,如果您喜欢还请帮忙点赞关注,谢谢![作揖]

Tags:

最近发表
标签列表