[英]RuntimeBinderException when trying to use dynamic type
im trying to implement log4net in my current log pattern i have setup but i ran into some problem when trying to convert my enum LogLevel to log4net's Level class. 即时尝试在我当前的日志模式中实现log4net我已经设置但是在尝试将我的枚举LogLevel转换为log4net的Level类时遇到了一些问题。
the problem lays in the ChangeLogLevelTo method: 问题出现在ChangeLogLevelTo方法中:
Exception: 例外:
An exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in System.Core.dll but was not handled in user code
System.Core.dll中出现“Microsoft.CSharp.RuntimeBinder.RuntimeBinderException”类型的异常,但未在用户代码中处理
Additional information: System.Reflection.TypeInfo does not contain any definition for info.
附加信息:System.Reflection.TypeInfo不包含info的任何定义。
Am i thinking this wrong or can i solve it like this: 我认为这是错的还是我可以像这样解决它:
public class Log4NetTargets : ILogTarget
{
public void Log(LogLevel logLevel, string correlationId, Type type, string member, string message, IDictionary<string, string> customData)
{
var log = log4net.LogManager.GetLogger(type);
var level = ChangeLogLevelTo<Level>(logLevel);
log.Logger.Log(type, level, string.Format("ID: {0} MESSAGE: {1} CUSTOM DATA: {2}", correlationId, message, customData ), new Exception());
}
public void Log(LogLevel logLevel, string correlationId, Type type, string member, Exception exception, IDictionary<string, string> customData)
{
var log = log4net.LogManager.GetLogger(type);
var level = ChangeLogLevelTo<Level>(logLevel);
log.Logger.Log(type, level, string.Format("ID: {0} EXCEPTION: {1} CUSTOM DATA: {2}", correlationId, exception, customData), new Exception());
}
private T ChangeLogLevelTo<T>(LogLevel logLevel)
{
var result = default(T);
dynamic dynamicType = typeof(T);
switch (logLevel)
{
case LogLevel.Error:
result = dynamicType.Error;
break;
case LogLevel.Info:
result = dynamicType.Info;
break;
case LogLevel.Trace:
result = dynamicType.Trace;
break;
case LogLevel.Warning:
result = dynamicType.Warn;
break;
}
return result;
}
Assuming that the various Level
types are all public static properties or fields on the specified type, the easiest way to accomplish this is with reflection: 假设各种
Level
类型都是指定类型的公共静态属性或字段,最简单的方法是使用反射:
public static class TypeExtensions
{
public static T GetStaticPropertyValueOfType<T>(this Type type, string name)
{
var property = type.GetProperty(name, BindingFlags.Public | BindingFlags.Static);
if (property != null
&& property.GetIndexParameters().Length == 0
&& typeof(T).IsAssignableFrom(property.PropertyType)
&& property.GetGetMethod(true) != null)
{
return (T)property.GetGetMethod(true).Invoke(null, new object [0]);
}
var field = type.GetField(name, BindingFlags.Public | BindingFlags.Static);
if (field != null
&& typeof(T).IsAssignableFrom(field.FieldType))
return (T) field.GetValue(null);
return default(T);
}
}
And then call it like 然后称之为
private T ChangeLogLevelTo<T>(LogLevel logLevel)
{
var result = default(T);
switch (logLevel)
{
case LogLevel.Error:
result = typeof(T).GetStaticPropertyValueOfType<T>("Error");
break;
case LogLevel.Info:
result = typeof(T).GetStaticPropertyValueOfType<T>("Info");
break;
case LogLevel.Trace:
result = typeof(T).GetStaticPropertyValueOfType<T>("Trace");
break;
case LogLevel.Warning:
result = typeof(T).GetStaticPropertyValueOfType<T>("Warn");
break;
}
return result;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.