Ответ 1
Проблема связана с тем, что с прозрачностью .NET 4 уровня 2 был введен. (Подробнее см. http://msdn.microsoft.com/en-us/library/dd233102.aspx.)
В методе override public void Attach(ILoggerRepository repository)
отсутствует SecuritySafeCriticalAttribute
. Добавление атрибута:
#if NET_4_0
[System.Security.SecuritySafeCritical]
#endif
override public void Attach(ILoggerRepository repository)
{
// ...
}
сделает проверку проверки IL. (Также см. http://msdn.microsoft.com/en-us/library/bb397858.aspx для получения дополнительной информации.)
Обновление: Чтобы пролить немного света на то, почему проверка завершается с ошибкой (что может быть не сразу понято, просто прочитав статьи в приведенных ссылках), вот короткое объяснение.
RemotingServices.Marshal
применяется атрибут [SecuritySafeCritical]
. Поэтому можно предположить, что вызов метода из прозрачного метода будет разрешен. Однако RemotingServices.Marshal
возвращает объект типа System.Runtime.Remoting.ObjRef
, и указанный тип аннотируется с атрибутом [SecurityCritical]
.
Если код log4net сохранит ссылку на возвращаемое значение в локальной переменной, Code Analysis обнаружит ошибку и выдаст CA2140 предупреждение ("Прозрачный код не должен ссылаться на важные элементы безопасности ").
Теперь, очевидно, в соответствии с правилами прозрачности безопасности прозрачный метод не может вызывать безопасный критически важный метод, если вызываемый метод возвращает критический тип безопасности, даже если прозрачный метод не сохраняет ссылку на возвращаемый объект, как показано в следующем примере:
public class TransparencyRulesDemo
{
[SecuritySafeCritical]
public void SafeGetCritical()
{
GetCritical();
}
public void TransparentGetCritical()
{
// Below line will trigger a CA2140 warning if uncommented...
// var critical = GetCritical();
// ...the following line on the other hand will not produce any warning
// but will lead to IL verification errors and MethodAccessExceptions if
// called from transparent code.
GetCritical();
}
[SecuritySafeCritical]
public Critical GetCritical()
{
return new Critical();
}
}
[SecurityCritical]
public class Critical
{
}
Это кстати. делает атрибут [SecuritySafeCritical]
на RemotingServices.Marshal
бессмысленным.