You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET分层项目中DI与仓储-服务模式的问题及正确实现咨询

.NET 7分层项目依赖注入与层访问问题解答

问题1:为什么Web API能够访问仓储层?

这是因为.NET的项目引用默认是传递性的:Web API直接引用了服务层,而服务层又引用了仓储层,所以仓储层的程序集会被间接传递给Web API项目。VS会自动检测到传递过来的程序集中的类型(包括仓储层的扩展方法),因此可以添加using MyApp.Repository;并调用对应的方法,即使Web API没有直接添加仓储层的项目引用。

问题2:如何阻止这种跨层访问的情况?

可以通过以下几种方式实现:

  • 设置私有项目引用:在服务层引用仓储层时,修改项目引用的属性,将PrivateAssets设置为all。这样仓储层的程序集不会被传递到Web API项目,Web API就无法访问仓储层的任何类型。
  • 拆分接口与实现:把仓储层的接口(如IMyRepository)单独提取到一个独立的类库项目(比如MyApp.Repository.Contracts)。服务层只引用这个接口项目,仓储层的实现项目引用接口项目。Web API仅引用服务层,无法接触到仓储层的实现类和扩展方法。
  • 使用internal访问修饰符:将仓储层的扩展方法、仓储实现类都标记为internal(默认就是internal,除非显式设为public),这样只有仓储层程序集内部可以访问,Web API即使拿到传递引用,也无法调用这些类型。

问题3:仓储类的正确DI实现方式是什么?是否应放弃在仓储层配置MongoDB客户端,转而在服务层编写统一的扩展方法?

两种方案都可行,取决于项目的分层复杂度和独立性需求:

方案一:保留仓储层的独立配置(推荐,保持分层职责)

优化现有实现,避免Web API直接操作仓储层:

  1. 将仓储层的AddRepository扩展方法改为internal,限制仅内部访问。
  2. 在服务层的扩展方法中统一调用仓储层的配置,同时把连接字符串参数传递进去:
// 服务层扩展方法修改
namespace MyApp.Service
{
    public static class ServiceCollectionExtensions
    {
        public static IServiceCollection AddServices(this IServiceCollection services, string mongoDbConnectionString)
        {
            // 内部调用仓储层的配置(服务层引用仓储层,且方法为internal,仅服务层可调用)
            services.AddRepository(mongoDbConnectionString);
            services.AddSingleton<IMyService, MyService>();

            return services;
        }
    }
}
  1. Web API的Program.cs只需要调用服务层的统一方法:
var mongoDbConnectionString = builder.Configuration.GetConnectionString("MongoDB");
builder.Services.AddServices(mongoDbConnectionString);
  1. 同时给服务层引用仓储层的项目设置PrivateAssets="all",彻底阻断Web API对仓储层的访问路径。

方案二:统一在服务层配置(适合简单项目)

如果项目分层不需要仓储层具备独立配置能力,可以把MongoDB客户端和仓储的注入逻辑移到服务层的扩展方法中。这种方式简化了配置,但会降低仓储层的独立性,当仓储层需要调整配置时,必须修改服务层代码。


内容的提问来源于stack exchange,提问作者Asheq Reza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 09:13:22