如何使用 HttpClientFactory 和 PolicyRegistry 传递记录器?
How do you pass a logger using HttpClientFactory and a PolicyRegistry?
我一直在阅读 this,它似乎有办法做我想做的事。
我显然有类似的东西,但在 PolicyContextExtensions
中,context.TryGetValue
需要 PolicyContextItems
。这对我来说显示为未定义的对象。
这是从哪里来的,怎么设置的?
此处供参考 PolicyContextExtensions
class:
public static class PolicyContextExtensions
{
public static bool TryGetLogger(this Context context, out ILogger logger)
{
if(context.TryGetValue(PolicyContextItems.Logger, out var loggerObject) && loggerObject is ILogger theLogger)
{
logger = theLogger;
return true;
}
logger = null;
return false;
}
}
Polly 的 Context class 基本上是 Dictionary<string, object>
.
这意味着您可以使用任意字符串注册任何类型的数据。
在教程中,斯蒂芬创建了一个新的上下文,如下所示:
var context = new Context($"GetSomeData-{Guid.NewGuid()}", new Dictionary<string, object>
{
{ PolicyContextItems.Logger, _logger }
});
- 任意字符串为
$"GetSomeData-{Guid.NewGuid()}"
- 其中数据是
Dictionary<string, object>
于是,他又在字典里面又编了一本字典。为什么?因为有了这个,您可以根据方法对要传递的数据进行分组(如 GetSomeData...
)
在这种情况下,PolicyContextItems.Logger
只是 logger
的字符串常量:
public static class PolicyContextItems
{
public const string Logger = "logger";
}
如果你想避免嵌套字典,但你想根据方法对它们进行分组,那么你可以简单地为键添加前缀并使用 Add
方法:
var context = new Context();
context.Add("GetSomeData-Logger", _logger);
context.Add("GetSomeData-XYZ", _xyz);
以上方案都是显式设置数据的key,容易出错。您不仅需要在策略创建期间知道该名称,而且还需要在您想要访问传递的数据时知道该名称。
一种更方便的方法是将密钥存储在 setter 和 getter 方法旁边:
public static class ContextExtensions
{
private static readonly string LoggerKey = "LoggerKey";
public static Context WithLogger(this Context context, ILogger logger)
{
context[LoggerKey] = logger;
return context;
}
public static ILogger GetLogger(this Context context)
{
if (context.TryGetValue(LoggerKey, out object logger))
{
return logger as ILogger;
}
return null;
}
}
此示例取自 official documentation。
我一直在阅读 this,它似乎有办法做我想做的事。
我显然有类似的东西,但在 PolicyContextExtensions
中,context.TryGetValue
需要 PolicyContextItems
。这对我来说显示为未定义的对象。
这是从哪里来的,怎么设置的?
此处供参考 PolicyContextExtensions
class:
public static class PolicyContextExtensions
{
public static bool TryGetLogger(this Context context, out ILogger logger)
{
if(context.TryGetValue(PolicyContextItems.Logger, out var loggerObject) && loggerObject is ILogger theLogger)
{
logger = theLogger;
return true;
}
logger = null;
return false;
}
}
Polly 的 Context class 基本上是 Dictionary<string, object>
.
这意味着您可以使用任意字符串注册任何类型的数据。
在教程中,斯蒂芬创建了一个新的上下文,如下所示:
var context = new Context($"GetSomeData-{Guid.NewGuid()}", new Dictionary<string, object>
{
{ PolicyContextItems.Logger, _logger }
});
- 任意字符串为
$"GetSomeData-{Guid.NewGuid()}"
- 其中数据是
Dictionary<string, object>
于是,他又在字典里面又编了一本字典。为什么?因为有了这个,您可以根据方法对要传递的数据进行分组(如 GetSomeData...
)
在这种情况下,PolicyContextItems.Logger
只是 logger
的字符串常量:
public static class PolicyContextItems
{
public const string Logger = "logger";
}
如果你想避免嵌套字典,但你想根据方法对它们进行分组,那么你可以简单地为键添加前缀并使用 Add
方法:
var context = new Context();
context.Add("GetSomeData-Logger", _logger);
context.Add("GetSomeData-XYZ", _xyz);
以上方案都是显式设置数据的key,容易出错。您不仅需要在策略创建期间知道该名称,而且还需要在您想要访问传递的数据时知道该名称。
一种更方便的方法是将密钥存储在 setter 和 getter 方法旁边:
public static class ContextExtensions
{
private static readonly string LoggerKey = "LoggerKey";
public static Context WithLogger(this Context context, ILogger logger)
{
context[LoggerKey] = logger;
return context;
}
public static ILogger GetLogger(this Context context)
{
if (context.TryGetValue(LoggerKey, out object logger))
{
return logger as ILogger;
}
return null;
}
}
此示例取自 official documentation。