使用依赖注入时在 .NET Core Web API 中的另一个 class 中使用 class 及其功能
Using a class and its features in another class in .NET Core Web API when using dependency injection
我有一个这样的 class,我想在控制器正在使用的另一个 class 中使用它的方法:
public class CommunicationApi
{
private readonly IConfiguration _configuration;
private readonly ILogger _logger;
private readonly MyAuthentication _myAuthentication;
public myEmail MyMail { get; set; }
public string[] Attachments { get; set; }
public bool IsBodyHtml { get; set; }
public CommunicationApi(ILogger<AdoExtract> logger, Func<string, myAuthentication> SAuth, IConfiguration configuration = null)
{
_configuration = configuration;
_logger = logger;
_myAuthentication = mAuth("ApiGatewayScope");
}
public async Task<int> SendMail()
{
//.....
}
}
我正在尝试在另一个 class 中使用这个 class 和方法,就像这样
public class AdoExtract : IAdoExtract
{
private readonly IConfiguration _configuration;
private readonly ILogger _logger;
private readonly Communication _com;
public AdoExtract(ILogger<AdoExtract> logger, IConfiguration configuration = null, CommunicationApi com = null)
{
_configuration = configuration;
_logger = logger;
_com = com;
}
public async Task<int> TestMail()
{
_com // here I am trying to set the properties of the above communication APIs such as MyEmail,Attachments
}
}
我需要在另一个 class 的 TestMail
函数中设置 communicationAPI
class 的属性。但是我没有得到任何我真正需要调用来发送电子邮件的属性或函数 SendMail()
。
在 startup.cs
我添加了 CommunicationAPI
这样的
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<CommunicationApi>();
}
我真的认为这不是正确的方法。请帮我解决这个问题。我对 DI 很陌生。
- 为您的 CommunicationApi 创建接口 class,您将在其中公开要执行的方法:
public interface ICommunication
{
Task<int> SendMail();
}
- 具体实现这个接口class (CommunicationApi)
public class CommunicationApi : ICommunication
- 在 ConfigureServices 方法中配置依赖:
services.AddScoped<ICommunication, CommunicationApi>();
- 重写你的消费者class:
public class AdoExtract : IAdoExtract
{
private readonly IConfiguration _configuration;
private readonly ILogger _logger;
private readonly ICommunication _com;
public AdoExtract(ILogger<AdoExtract> logger, IConfiguration configuration,
ICommunication com)
{
_configuration = configuration;
_logger = logger;
_com = com;
}
public async Task<int> TestMail()
{
int result = await _com.SendMail();
}
}
由于您希望 DI 将 CommunicationApi
注入 AdoExtract
,您需要确保 DI 容器具有创建 CommunicationApi
实例所需的所有信息,即一个 ILogger<AdoExtract>
、一个 Func<string, myAuthentication>
和一个 IConfiguration
;否则无法调用 CommunicationApi
的构造函数。在您的情况下,最有可能缺少的是 Func
。虽然您肯定可以通过为特定类型注册一个实例来注入它,但我怀疑这是一个好主意,因为 Func<>
不够具体。考虑创建一个包装它的接口,然后注册一个实例:
public interface IAuthenticationFactory {
MyAuthentication AuthenticationForKey(string key);
}
在ConfigureServices
中注册这个接口的实现,然后注入它而不是Func
,并在构造函数中调用AuthenticationForKey("ApiGatewayScope")
。
注意:传递一个完整的 IConfiguration
对象可以让接收方 class 访问比它需要的更多的信息。使用 Options
pattern 来解决这个缺点。
您可以重构您的代码,创建一个单独的 class 包含所有属性。
class ApiData
{
public myEmail MyMail { get; set; }
public string[] Attachments { get; set; }
public bool IsBodyHtml { get; set; }
}
然后,您创建一个包含您的通信服务的所有方法的接口。
public interface ICommunicationApiService
{
Task<int> SendMail();
//...All your methods
}
在那之后你的 Class CommunicationApi 应该实现那个接口
public class CommunicationApiService :ICommunicationApiService
{
private readonly IConfiguration _configuration;
private readonly ILogger _logger;
private readonly MyAuthentication _myAuthentication;
public CommunicationApi(ILogger<AdoExtract> logger, Func<string,
myAuthentication> SAuth, IConfiguration configuration = null)
{
_configuration = configuration;
_logger = logger;
_myAuthentication = mAuth("ApiGatewayScope");
}
public async Task<int> SendMail()
{
//.....Your implementation
}
//....
}
注册服务后:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<ICommunicationApiService,CommunicationApiService>();
}
当你想使用你的服务时,你只需在构造函数中传递接口,在运行时服务将被解析。
public class AdoExtract : IAdoExtract
{
private readonly IConfiguration _configuration;
private readonly ILogger _logger;
private readonly ICommunicationApiService _communicationApiService;
public AdoExtract(ILogger<AdoExtract> logger,
IConfiguration configuration = null,
ICommunicationApiService _communicationApiService)
{
_configuration = configuration;
_logger = logger;
_communicationApiService = communicationApiService;
}
public async Task<int> TestMail()
{
// here you create your ApiData object and then use your Api service ....
}
我有一个这样的 class,我想在控制器正在使用的另一个 class 中使用它的方法:
public class CommunicationApi
{
private readonly IConfiguration _configuration;
private readonly ILogger _logger;
private readonly MyAuthentication _myAuthentication;
public myEmail MyMail { get; set; }
public string[] Attachments { get; set; }
public bool IsBodyHtml { get; set; }
public CommunicationApi(ILogger<AdoExtract> logger, Func<string, myAuthentication> SAuth, IConfiguration configuration = null)
{
_configuration = configuration;
_logger = logger;
_myAuthentication = mAuth("ApiGatewayScope");
}
public async Task<int> SendMail()
{
//.....
}
}
我正在尝试在另一个 class 中使用这个 class 和方法,就像这样
public class AdoExtract : IAdoExtract
{
private readonly IConfiguration _configuration;
private readonly ILogger _logger;
private readonly Communication _com;
public AdoExtract(ILogger<AdoExtract> logger, IConfiguration configuration = null, CommunicationApi com = null)
{
_configuration = configuration;
_logger = logger;
_com = com;
}
public async Task<int> TestMail()
{
_com // here I am trying to set the properties of the above communication APIs such as MyEmail,Attachments
}
}
我需要在另一个 class 的 TestMail
函数中设置 communicationAPI
class 的属性。但是我没有得到任何我真正需要调用来发送电子邮件的属性或函数 SendMail()
。
在 startup.cs
我添加了 CommunicationAPI
这样的
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<CommunicationApi>();
}
我真的认为这不是正确的方法。请帮我解决这个问题。我对 DI 很陌生。
- 为您的 CommunicationApi 创建接口 class,您将在其中公开要执行的方法:
public interface ICommunication
{
Task<int> SendMail();
}
- 具体实现这个接口class (CommunicationApi)
public class CommunicationApi : ICommunication
- 在 ConfigureServices 方法中配置依赖:
services.AddScoped<ICommunication, CommunicationApi>();
- 重写你的消费者class:
public class AdoExtract : IAdoExtract
{
private readonly IConfiguration _configuration;
private readonly ILogger _logger;
private readonly ICommunication _com;
public AdoExtract(ILogger<AdoExtract> logger, IConfiguration configuration,
ICommunication com)
{
_configuration = configuration;
_logger = logger;
_com = com;
}
public async Task<int> TestMail()
{
int result = await _com.SendMail();
}
}
由于您希望 DI 将 CommunicationApi
注入 AdoExtract
,您需要确保 DI 容器具有创建 CommunicationApi
实例所需的所有信息,即一个 ILogger<AdoExtract>
、一个 Func<string, myAuthentication>
和一个 IConfiguration
;否则无法调用 CommunicationApi
的构造函数。在您的情况下,最有可能缺少的是 Func
。虽然您肯定可以通过为特定类型注册一个实例来注入它,但我怀疑这是一个好主意,因为 Func<>
不够具体。考虑创建一个包装它的接口,然后注册一个实例:
public interface IAuthenticationFactory {
MyAuthentication AuthenticationForKey(string key);
}
在ConfigureServices
中注册这个接口的实现,然后注入它而不是Func
,并在构造函数中调用AuthenticationForKey("ApiGatewayScope")
。
注意:传递一个完整的 IConfiguration
对象可以让接收方 class 访问比它需要的更多的信息。使用 Options
pattern 来解决这个缺点。
您可以重构您的代码,创建一个单独的 class 包含所有属性。
class ApiData
{
public myEmail MyMail { get; set; }
public string[] Attachments { get; set; }
public bool IsBodyHtml { get; set; }
}
然后,您创建一个包含您的通信服务的所有方法的接口。
public interface ICommunicationApiService
{
Task<int> SendMail();
//...All your methods
}
在那之后你的 Class CommunicationApi 应该实现那个接口
public class CommunicationApiService :ICommunicationApiService
{
private readonly IConfiguration _configuration;
private readonly ILogger _logger;
private readonly MyAuthentication _myAuthentication;
public CommunicationApi(ILogger<AdoExtract> logger, Func<string,
myAuthentication> SAuth, IConfiguration configuration = null)
{
_configuration = configuration;
_logger = logger;
_myAuthentication = mAuth("ApiGatewayScope");
}
public async Task<int> SendMail()
{
//.....Your implementation
}
//....
}
注册服务后:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<ICommunicationApiService,CommunicationApiService>();
}
当你想使用你的服务时,你只需在构造函数中传递接口,在运行时服务将被解析。
public class AdoExtract : IAdoExtract
{
private readonly IConfiguration _configuration;
private readonly ILogger _logger;
private readonly ICommunicationApiService _communicationApiService;
public AdoExtract(ILogger<AdoExtract> logger,
IConfiguration configuration = null,
ICommunicationApiService _communicationApiService)
{
_configuration = configuration;
_logger = logger;
_communicationApiService = communicationApiService;
}
public async Task<int> TestMail()
{
// here you create your ApiData object and then use your Api service ....
}