这是为了一个学习项目.当派生类在其构造函数中调用base(参数)时,如何才能将IHttpContextAccessor或任何类注入基本服务类而不将其注入派生类?

我试图避免将依赖项添加到它们的构造函数中的所有派生类,因为它们不会使用它.我有一个基地服务班级:

type namespace MagicVilla_Web.Services
{
    public class BaseService : IBaseService
    {
        public IHttpClientFactory httpClient { get; set; }
        public APIResponse responseModel { get; set; }

       ** public IHttpContextAccessor httpContextAccessor;** //  <== I want to inject this in this class

        public BaseService(IHttpClientFactory httpClient)
        {
            this.responseModel = new();
            this.httpClient = httpClient;         
        }

        public async Task<T> SendAsync<T>(APIRequest apiRequest)
        {
           // do a bunch of stuff
        }
}

以及从BaseService类继承但在其构造函数中显式调用BaseService的派生类.SendAsync&lt;T&gt;函数的公共业务逻辑在BaseService类中,这就是我希望将IHttpConextAccessor注入BaseService类的原因.

每当我注入和调用这些派生服务类时,它们都会使用1个参数调用base Service构造函数,而我似乎找不到一种让依赖项注入工作的方法

namespace MagicVilla_Web.Services
{
    public class AuthService : BaseService, IAuthService
    {
        private readonly IHttpClientFactory _clientFactory;
        private string villaUrl;

        public AuthService(IHttpClientFactory clientFactory, IConfiguration configuration)  : base(clientFactory)
        {
            _clientFactory = clientFactory;
            villaUrl = configuration.GetValue<string>("ServiceUrls:VillaAPI");
        }

        public Task<T> RegisterAsync<T>(RegistrationRequestDTO obj)
        {
            return SendAsync<T>(new APIRequest()
            {
             //call base class SendAsync with arguments
            });
        }

从BaseService继承的另一个服务类

namespace MagicVilla_Web.Services
{
    public class VillaService : BaseService, IVillaService 
    {

        private readonly IHttpClientFactory _clientFactory;
        private string villaUrl;

        public VillaService(IHttpClientFactory clientFactory, IConfiguration configuration) : base(clientFactory)
        {
            _clientFactory = clientFactory;
            villaUrl = configuration.GetValue<string>("ServiceUrls:VillaAPI");
            
        }

        public Task<T> CreateAsync<T>(VillaCreateDTO dto)
        {
            return SendAsync<T>(new APIRequest()
            {
     //call base class SendAsync with arguments
            });

        }

我try 将多个构造函数添加到基类,但这不起作用,因为基类从不直接调用,其方法仅通过派生类调用,因此双参数构造函数不起作用.

type namespace MagicVilla_Web.Services
{
    public class BaseService : IBaseService
    {

        public IHttpClientFactory httpClient { get; set; }
        public APIResponse responseModel { get; set; }
        public IHttpContextAccessor httpContextAccessor;

public BaseService(IHttpClientFactory httpClient,IHttpContextAccessor httpContextAccessor ) // <== does not work
        {
            this.responseModel = new();
            this.httpClient = httpClient;  
            this.httpContextAccessor = httpContextAccessor;
        }

        public BaseService(IHttpClientFactory httpClient)
        {
            this.responseModel = new();
            this.httpClient = httpClient;         
        }


}

如果我将注入类添加到所有派生构造函数及其对基类的调用中,那么注入确实有效,但这似乎很难维护.

AuthService(IHttpClientFactory clientFactory, IConfiguration configuration, IHttpContextAccessor httpContextAccessor)  : base(clientFactory, httpContextAccessor)

VillaService(IHttpClientFactory clientFactory, IConfiguration configuration, IHttpContextAccessor httpContextAccessor) : base(clientFactory, httpContextAccessor)

My Program.cs中的所有内容都应正确设置.我不会在任何地方注入BaseService类.

            builder.Services.AddScoped<IVillaService, VillaService>();
            builder.Services.AddScoped<IVillaNumberService, VillaNumberService>();
            builder.Services.AddScoped<IAuthService, AuthService>();
         
            builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();```

有没有某种方法可以在不更改派生类的构造函数的情况下将IHttpConextAccessor注入BaseService类中?

我查看了文档,没有看到任何特别引用此用例的内容.https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection-usage

推荐答案

如果我将注入类添加到所有派生构造函数及其对基类的调用中,那么注入确实有效,但这似乎很难维护.

事实上,这就是C#中继承的工作方式(以及我非常熟悉的所有其他语言,我可以将其与之进行比较).如果基类depends依赖于某个东西,那么当另一个类从它继承时,这种依赖关系不会消失.

因此,要么通过链接来提供依赖项(如操作or所示),要么将特定实例硬编码到派生类中(通常不推荐).

这很难维护吗?

是的,是这样的.

解决方案是什么?

比起类继承,更喜欢对象组合.

-Design Patterns-Design Patterns

不要将继承用作代码重用的工具.取而代之的是,只在你需要的时候提供你需要的inject项服务.

Don't use inheritance at all章如果你不明白的话抛弃BaseService类,代之以提供实现类似SendAsync行为的服务.需要该行为的类可以将该服务注入到它们的构造函数中,而不忽略它的类.

从2002年开始,我就一直在用C#编程,十多年来我一直没有使用继承.没有它,你很容易就能 payable 过go .这样的话,事情会变得更容易.

Csharp相关问答推荐

CS0103 dlibdotnet和www.example.com facerect不在上下文中

Blazor服务器端的身份验证角色

C#-VS2022:全局使用和保存时的代码清理

Unix上的.NET(核心):.NET意外地未看到通过P/Invoke系统调用对环境变量进行的进程内修改

如何使用EF Core和.NET 8来upsert到具有多对多关系的表?

C#Null判断处理失败

确定System.Text.Json序列化中是否无法识别Type

使用System.Text.Json进行序列化时发生StackOverflow异常

MSTest--将消息直接写入StdOut和使用TestContext有什么不同?

为什么在使用JsonDerivedType序列化泛型时缺少$type?

C#System.Commandline:如何向命令添加参数以便向其传递值?

为什么我在使用有效令牌的情况下仍未获授权?

数据库操作预计影响1行,但实际影响0行; after _dbContext.SaveChanges();

当`JToken?`为空时?

从MudAutoComplete打开对话框,列表仍然可见

使用C#代码和SQL SERVER中的相同证书签名会产生不同的结果

处理方法内部过滤与外部过滤

如何将行添加到DataGrid以立即显示它?

将两个JSON文件与覆盖值的主文件合并

自定义ConsoleForMatter中的DI/Http上下文