扩展类的依赖注入?

问题描述 投票:0回答:4

我使用 Microsoft Unity 作为我的 IoC 容器。我有许多扩展类,它们为我的业务对象添加了有用的方法 这是我今天使用的代码:

public static class BusinessObjectExtensions
{
    public static bool CanDoStuff(this BusinessObject obj) 
    {
        var repository = BusinessHost.Resolver.Resolve<IRepository>();
        var args = new EArgument { Name = obj.Name };
        return repository.AMethod(obj.UserName, args);
    }
}

有没有更好的方法来管理扩展类的依赖注入?

c# .net ioc-container
4个回答
32
投票

构造函数注入的事实上的默认依赖注入方式对于静态类是不可能的。可以使用如下所示的参数注入,但这不是一个非常干净的方法。

public static class BusinessObjectExtensions
{
    public static bool CanDoStuff(this BusinessObject obj, IRepository repository)
    {
        var args = new EArgument { Name = obj.Name };
        return repository.AMethod(obj.UserName, args);
    }
}

23
投票

您实际上应该尝试避免扩展方法,除非它们仅适用于内部数据(类本身的属性)或方法中提供的简单数据类型。您不应该在扩展方法中与其他依赖项进行交互。如果遵循此规则,则根本不需要使用 IoC 注入扩展类。


7
投票

你为什么要这么做?

这将应用程序中的耦合提升到了极限,并且可能会让您的队友在使用扩展方法时感到非常困惑(他们必须记住每次使用该方法时都注入存储库)。

相反,创建一个单独的类并使用构造函数注入来注入

IRepository
实例:

public class StuffExecuter    
{
    private readonly IRepository _repository;

    public StuffExecuter(IRepository repository)
    {
        _repository = repository;
    }

    public bool CanExecute(BusinessObject obj)
    {
        _repository.Add(obj.UserName, new EArgument
        {
            Name = obj.Name
        });
    }
}

0
投票

示例:使用扩展类进行依赖注入

这是在 ASP.NET Core 中使用 DI 扩展类的完整示例。

1。添加所需的 NuGet 包 确保您已安装所需的软件包:

dotnet 添加包 Microsoft.Extensions.DependencyInjection.Abstractions

2。创建扩展类 扩展类封装了服务注册以更好地组织。下面是 DependencyInjection 命名空间中名为 AddDependencyInjection 的类:

using Microsoft.Extensions.DependencyInjection;
using dumdum.Interface;
using dumdum.Model.DB;
using dumdum.Service.Implementation;
using dumdum.Service.Interface;
using Sieve.Services;
using Microsoft.EntityFrameworkCore;
using Microsoft.OpenApi.Models;
using System.Text;
using Microsoft.IdentityModel.Tokens;

namespace dumdum.DependencyInjection
{
    public static class AddDependencyInjection
    {
        public static IServiceCollection AddDependencies(this IServiceCollection services)
        {
            // Database Context
            services.AddDbContext<Context>(options =>
                options.UseSqlServer(Environment.GetEnvironmentVariable("CodeXMinioService")));

            // General Services
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>));
            services.AddScoped<IUnitOfWork, UnitOfWork>();
            services.AddScoped(typeof(IBaseService<,>), typeof(BaseService<,>));
            services.AddScoped<ISieveProcessor, SieveProcessor>();
            services.AddScoped<ISQLORMService, DapperORMService>();

            // Business Logic Services
            services.AddScoped<IUploadService, UploadService>();
            services.AddScoped<IUserMaster, UserMasterService>();

            // JWT Authentication
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuerSigningKey = true,
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("your_secret_key_here")),
                        ValidateIssuer = false,
                        ValidateAudience = false,
                        ValidateLifetime = true,
                        ClockSkew = TimeSpan.Zero
                    };
                });

            return services;
        }
    }
}

3.使用Program.cs中的扩展方法 扩展类到位后,DI 注册可以轻松包含在应用程序的主入口点中:

using dumdum.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();

builder.Services.AddDependencies(); // Adding dependencies via extension method

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the middleware pipeline
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();
app.Run();

示例中的要点

服务封装:所有的服务注册都封装在AddDependency方法中,提高了可重用性和可维护性。 模块化方法:每种类型的服务(例如,DbContext、存储库、业务逻辑服务)都按逻辑分组。 JWT 身份验证:通过使用令牌验证参数配置 AddJwtBearer 来保护您的 API。

该方法的好处

可扩展性:随着应用程序的增长,轻松向扩展方法添加更多服务。 代码组织:将 DI 逻辑与应用程序启动代码分开。 可测试性:通过提供集中的模拟服务位置来简化单元测试。

© www.soinside.com 2019 - 2024. All rights reserved.