首页 > 解决方案 > 如何使用依赖注入的内部类

问题描述

我的解决方案的结构如下

API -> 业务逻辑 - 数据访问

API 使用业务逻辑拥有的服务。例如项目服务。该服务具有具有以下签名的方法Task<ProjectGetDto>GetProjectById(int id)。现在我开始意识到我的服务不能被重用。所以我添加了一个额外的“层”,即位于 API 和业务逻辑之间的外观层。业务逻辑现在只真正处理实体。外观将这些实体转换为 Dtos 以供 API 使用。这些服务现在是更多的存储库(我将重命名这些)。这意味着我可以在整个业务逻辑中重用这些存储库。

我正在努力解决的问题是技术上任何东西都可以使用该业务逻辑。我有点想隐藏这些存储库,以便只有外观可以看到/使用它们。在该项目之外,没有任何东西可以使用这些存储库。没有什么可以阻止 api 注入存储库并直接使用它。所以我开始研究内部类。但是,通过依赖注入,我只看到了如何使其工作。

我添加了一个扩展方法来在业务逻辑中添加所需的存储库。知道 API 看不到它们。但是,如果我尝试将存储库注入到外观中,我会收到一个错误,指出注入类比尝试使用它的类更难访问。

我觉得依赖注入阻止我封装我的代码

我现在解决这些问题的方法是使外观层成为一个新项目,并让 API 引用外观项目,并且外观现在引用业务逻辑。但是我仍然觉得业务逻辑没有被封装,因为它仍然可以以我不希望的方式使用

标签: api.net-coredependency-injectionarchitecture

解决方案


我找到了我的问题的答案。
我可以使用以下模式来实现我想要的。

命名空间 AssemblyOne {

public interface IEmployeeRepo {
    void Insert();
    void Update();
}


internal class DBEmployeeRepo: IEmployeeRepo {
    
    public void Insert() {}
    public void Update() {}

}


public class EmployeeFacade: IEmployeeRepo {
    private readonly IEmployeeRepo _repo;

    public EmployeeFacade(IEmployeeRepo repo) => _repo = repo;

    public Insert() => _repo.Insert();
    public Update() => _repo.Update();
}


public static class Setup
{
    public static IServiceCollection SetupShared(this IServiceCollection services, IConfiguration config)
    {
        return services
            .AddScoped<IEmployeeRepo>(sp => new EmployeeFacade(new DBEmployeeRepo()))
        ;
    }
}   

}

使用 AssemblyOne;

命名空间 AssemblyTwo.Web {

public class Startup {
    publci IConfiguration Config;

    public Startup(IConfiguration config) => Config = config;

    public void ConfigureServices(IServiceCollection services)
    {
        services.SetupShared(Config);
    }
}

public class WorkService {
    private readonly IEmployeeRepo _repo;

    public WorkService(IEmployeeRepo repo) => _repo = repo;

    public void DoSomething() {
        _repo.Insert();
    }

}

}


推荐阅读