从字符串 C# 中检索对象
Retrieve Object From String C#
我有下面的映射器 json 文件,它告诉我对于给定的异常,我想使用哪种错误处理策略。
{
"ExceptionMappers": [
{
"ExceptionName": "TimeoutException",
"ExceptionType": "Transient",
"Policy": "WaitAndRetry",
"WaitType": "Linear"
},
{
"ExceptionName": "DivideByZeroException",
"ExceptionType": "Permanent",
"Policy": "CircuitBreaker"
},
{
"ExceptionName": "WhosebugException",
"ExceptionType": "LogOnly",
"Policy": "WaitAndRetry",
"WaitType": "Linear"
}
]
}
然后使用下面的代码,我试图获取异常类型并应用可以调用操作的策略。但是我卡住了,如何从字符串名称中获取异常类型。
public void Execute(Action action, string exceptionName)
{
var filePath = @"appsetting.json";
var exceptionMapperJson = System.IO.File.ReadAllText(filePath);
var rootNode = JsonConvert.DeserializeObject<RootObject>(exceptionMapperJson);
var exceptionNode = rootNode.ExceptionMappers.FirstOrDefault(e => e.ExceptionName.Equals(exceptionName));
var exceptionObject = Type.GetType(exceptionName);
if (exceptionNode != null)
{
// Here I need the exception from the string value
Policy.Handle<TimeoutException>().Retry().Execute(action);
}
else
{
// No Policy applied
Policy.NoOp().Execute(action);
}
}
根据@thehennyy 的评论,Jon Skeet's answer to a similar question 介绍了当泛型类型仅在运行时已知时如何使用反射来调用泛型方法。与链接答案的细微差别:因为 .Handle<TException>()
是 Policy
上的静态方法,所以将 null
作为第一个参数传递给 MethodInfo.Invoke()
。
或者,因为 Polly offers Handle clauses which can take a predicate,您可以简单地:
var exceptionType = Type.GetType(exceptionName);
if (exceptionNode != null)
{
Policy.Handle<Exception>(e => exceptionType.IsAssignableFrom(e.GetType())) // etc
}
这 live dotnetfiddle example 证明它有效。
或者,使您的包装器方法本身通用:
public void Execute<TException>(Action action) where TExecption : Exception
{
// reverses the approach:
// you'll want a typeof(TException).Name, to get the string name of the exception from TException
// Then you can just Policy.Handle<TException>(...) when you construct the policy
}
作为另一个改进,您可以考虑在启动时只构建一次策略,并将它们放在 PolicyRegistry
我有下面的映射器 json 文件,它告诉我对于给定的异常,我想使用哪种错误处理策略。
{
"ExceptionMappers": [
{
"ExceptionName": "TimeoutException",
"ExceptionType": "Transient",
"Policy": "WaitAndRetry",
"WaitType": "Linear"
},
{
"ExceptionName": "DivideByZeroException",
"ExceptionType": "Permanent",
"Policy": "CircuitBreaker"
},
{
"ExceptionName": "WhosebugException",
"ExceptionType": "LogOnly",
"Policy": "WaitAndRetry",
"WaitType": "Linear"
}
]
}
然后使用下面的代码,我试图获取异常类型并应用可以调用操作的策略。但是我卡住了,如何从字符串名称中获取异常类型。
public void Execute(Action action, string exceptionName)
{
var filePath = @"appsetting.json";
var exceptionMapperJson = System.IO.File.ReadAllText(filePath);
var rootNode = JsonConvert.DeserializeObject<RootObject>(exceptionMapperJson);
var exceptionNode = rootNode.ExceptionMappers.FirstOrDefault(e => e.ExceptionName.Equals(exceptionName));
var exceptionObject = Type.GetType(exceptionName);
if (exceptionNode != null)
{
// Here I need the exception from the string value
Policy.Handle<TimeoutException>().Retry().Execute(action);
}
else
{
// No Policy applied
Policy.NoOp().Execute(action);
}
}
根据@thehennyy 的评论,Jon Skeet's answer to a similar question 介绍了当泛型类型仅在运行时已知时如何使用反射来调用泛型方法。与链接答案的细微差别:因为 .Handle<TException>()
是 Policy
上的静态方法,所以将 null
作为第一个参数传递给 MethodInfo.Invoke()
。
或者,因为 Polly offers Handle clauses which can take a predicate,您可以简单地:
var exceptionType = Type.GetType(exceptionName);
if (exceptionNode != null)
{
Policy.Handle<Exception>(e => exceptionType.IsAssignableFrom(e.GetType())) // etc
}
这 live dotnetfiddle example 证明它有效。
或者,使您的包装器方法本身通用:
public void Execute<TException>(Action action) where TExecption : Exception
{
// reverses the approach:
// you'll want a typeof(TException).Name, to get the string name of the exception from TException
// Then you can just Policy.Handle<TException>(...) when you construct the policy
}
作为另一个改进,您可以考虑在启动时只构建一次策略,并将它们放在 PolicyRegistry