I am getting "Cannot serialized the aspects: Type 'log4net.Core.LogImpl' in assembly 'log4net...'" -how can I make it serializable?
Asked Answered
C

1

5

Environment

  • Windows 7 x64
  • PostSharp 2.1.7.30 installed
  • PostSharp 2.1.7.29 (reference retrieved from the PostSharp install directory)
  • log4net 1.2.11.0 (reference retrieved from the net\2.0\release directory of the log4net binaries download)
  • ASP.NET 2.0 application
  • Visual Studio 2010 SP1

Aspect

[Serializable]
public class MethodBoundaryAspect : PostSharp.Aspects.OnMethodBoundaryAspect
{
    ILog _logger = LogManager.GetLogger("MethodBoundaryAspect");

    public override void OnEntry(PostSharp.Aspects.MethodExecutionArgs args)
    {
        _logger.DebugFormat("The user {0} entered the method {1} at {2}.",
            HttpContext.Current.Profile.UserName,
            args.Method.Name,
            DateTime.Now);

        base.OnEntry(args);
    }

    public override void OnExit(PostSharp.Aspects.MethodExecutionArgs args)
    {
        _logger.DebugFormat("The user {0} exited the method {1} at {2}.",
            HttpContext.Current.Profile.UserName,
            args.Method.Name,
            DateTime.Now);

        base.OnExit(args);
    }

    public override void OnException(PostSharp.Aspects.MethodExecutionArgs args)
    {
        _logger.DebugFormat("The user {0} was executing the method {1} when an unhandled exception occurred at {2}.{3}{4}",
            HttpContext.Current.Profile.UserName,
            args.Method.Name,
            DateTime.Now,
            Environment.NewLine,
            args.Exception.ToString());

        base.OnException(args);
    }
}

Compile Error

Cannot serialize the aspects: Type 'log4net.Core.LogImpl' in Assembly 'log4net, Version=1.2.11.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a' is not marked as serializable.

How can I make the log4net.Core.LogImpl serializable so that I can compile this solution?

Conative answered 26/4, 2013 at 14:36 Comment(8)
Place the logger outside the class as a static object. Make a new Method inside your class that initializes the logger first.Alcine
Also, you have a serializable class that has no members (properties) to serialize. (!)Alcine
You will need to do manual serialization.Desist
@GrantThomas, would it be safe to declare it like this public static ILog Logger = LogManager.GetLogger("MethodBoundaryAspect"); in the Global.asax? I feel like multiple threads would cause some serious problems here as multiple users use the system. Thus going back to your statement, manual serialization.Conative
@mtsiakiris, serialization happens on more than just Properties, PostSharp is trying to serialize the field created for _logger. Thus as Grant stated, I may have to do this serialization by hand.Conative
This is true, but the serialization output will come from a new class that you have to implement. Another thing is that yoy can not have a "serialized instance" of _logger, firstly because log4net does not allow it and second, what would be the use of getting a serialized logger from one machine to another, you have to make a new instance there. I dont know exactly what you are trying to accompish, sorry.Alcine
@MichaelPerrenoud That statement itself would be safe, but I've no idea if the instance of a thing returned by GetLogger is in and of itself a thread-safe type.Desist
@GrantThomas, I ended up setting it as [NonSerialized] since the serialization is only occurring for the purposes of PostSharp to do its IL generation.Conative
C
11

Based on the comments from Grant and mtsiakiris I solved this problem by adding the [NonSerialized] attribute to the field like this:

[NonSerialized]
ILog _logger = LogManager.GetLogger("MethodBoundaryAspect");

which then just ignored it during serialization. The reason this occurs is because PostSharp needs to serialize the attribute during its IL generation.

Conative answered 26/4, 2013 at 15:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.