Проблема связана с тем, что в .NET 4 Level 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
бессмысленным.