【问题标题】:Dependency Injection Involving Struct types涉及结构类型的依赖注入
【发布时间】:2022-09-28 02:15:12
【问题描述】:

我有一个如下所示的课程,

public class AccessToken : IAuthToken
{
    /// <summary>
    /// Initializes a new instance of the <see cref=\"AccessToken\"/> class.
    /// </summary>
    /// <param name=\"token\">The token.</param>
    /// <param name=\"validTo\">The valid to.</param>
    public AccessToken(string token, DateTimeOffset validTo)
    {
        ValidTo = validTo;
        Token = token;
    }

    ///<inheritdoc />
    public DateTimeOffset ValidTo { get; private set; }

    /// <summary>
    /// Gets the RAW Jwt token value. 
    /// This value is encoded and represents the Jwt token.
    /// </summary>
    /// <value>
    /// The token.
    /// </value>
    public string Token { get; private set; }
}

DI代码是这样的,

return services
    .AddTransient<IAuthToken, AccessToken>()
    .AddTransient<IAuthTokenService, AuthTokenService>()
    .AddSingleton<IIdentityDiscovery, IdentityDiscovery>()
    .AddTransient<IIdentityTokenClient, IdentityTokenClient>()
    .AddTransient<IDiscoveryClientRetryPolicy, DiscoveryClientRetryPolicy>()
    .AddTransient<ITokenClientRetryPolicy, TokenClientRetryPolicy>()
    .AddSingleton<IRetryPolicyOptions>(provider => retryOptions);

整个东西被打包成一个nuget。当从 .net461 调用此 DI 代码时,它工作正常,但在 net core 6 中使用时,我收到一条错误消息,指出它无法解析类型字符串和DateTimeOffset。我试图注入一个虚拟字符串,字符串错误消失了,但结构 DateTimeOffset 仍然存在。 .net6 是否以不同的方式解释此 DI?

  • 系统的反应对我来说听起来很合理。注入构造函数的所有内容都需要通过 servicecollection 找到或创建。为什么它首先在早期的框架版本中工作?那里会注入什么?
  • 您是否实际上在系统的任何位置注入了 IAccessToken?也许它实际上从未使用过,因此在早期版本中被忽略了,但现在系统检查注册是否有意义。
  • 我不相信它在 .NET 4.6.1 中运行良好。也许在您的代码版本中,服务集合未经过验证,而在 ASP.NET Core 3 及更高版本的开发人员环境中,所有注册都经过验证。尝试在 .NET 4.6.1 应用程序中解析 IAuthToken 仍然会导致错误。由于拉尔夫提到的原因,它根本无法工作。
  • 感谢你们。有没有办法可以注入一个虚拟结构?到目前为止,我无法更改 nuget 代码库。这是一个旧代码,您说得对,实际上不需要 AccessToken 注入。我只想保持 nuget 中的内容并继续向 DateTimeOffset 进行虚拟注入,这对于结构类型似乎是不可能的

标签: c# .net .net-core dependency-injection .net-4.6


【解决方案1】:

如果您的 nuget 包中的类尝试解析此 IAuthToken 实例,那么您可以将以下注册添加到您的主应用程序以覆盖来自 nuget 的注册。注册顺序很重要,因此请务必先从您的 nuget 执行服务注册。

services.AddTransient<IAuthToken, AccessToken>(
    serviceProvider =>
    {
        // You can resolve any service that can provide the token and validTo parameters.
        var tokenInfoProvider = serviceProvider.GetRequiredService<...>();

        // Get the parameter values.
        // Either from the tokenInfoProvider or specify it directly here.
        string token = String.Empty;
        DateTimeOffset validTo = DateTimeOffset.UtcNow.AddHours(1);

        // Create and return the access token instance.
        return new AccessToken(token, validTo);
    }
);

如果只有应用程序尝试解析IAuthToken,那么我建议创建一个工厂(例如IAccessTokenFactory),您可以使用它来动态创建具有特定ctor 参数的AccessToken 实例。然后注册它的实现并注入IAccessTokenFactory 你需要得到一个新的IAuthToken 实例。这样您就可以保持现在的 nuget 代码。

public interface IAccessTokenFactory
{
    IAuthToken Create(string token, DateTimeOffset validTo);
}

public class AccessTokenFactory : IAccessTokenFactory
{
    public IAuthToken Create(string token, DateTimeOffset validTo)
    {
        return new AccessToken(token, validTo);
    }
}

// register this instead of the AccessToken
services.AddSingleton<IAccessTokenFactory, AccessTokenFactory>();

【讨论】:

    猜你喜欢
    • 2018-06-29
    • 1970-01-01
    • 2016-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-02
    • 1970-01-01
    相关资源
    最近更新 更多