I would like to make a snapshot of all the static non herited variable in all my assemblies at a given point in time in order to be able to restore them later on.
I have the CustomMemberInfo
which store information of a static variable :
public class CustomMemberInfo
{
public string name;
public Type type;
public object value;
public CustomMemberInfo(string n, Type t, object v)
{
name = n;
type = t;
value = v;
}
}
And I try to serialize this static context like this :
private void saveStaticCache(string outputDirectory, JsonSerializerSettings settings)
{
if (ConfigurationManager.AppSettings["saveStaticState"] == "true")
{
AppDomain currentDomain = AppDomain.CurrentDomain;
// Get all the loaded assemblies which are not installed in the global assembly cache. Means ignoring all System.XXX assemblies
var assemblies = currentDomain.GetAssemblies().Where(assem => assem.GlobalAssemblyCache == false);
List<CustomMemberInfo> statics = new List<CustomMemberInfo>();
foreach (Assembly asm in assemblies)
{
foreach (Type t in asm.GetTypes())
{
if (t.IsGenericType || t.IsGenericParameter | t.IsConstructedGenericType | t.IsGenericTypeDefinition)
{
continue;
}
CustomMemberInfo[] staticFields = t
.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)
.Where(field => field.IsNotSerialized == false && field != null && field.FieldType.IsGenericParameter == false && field.GetValue(null) != null)
.Select(field => new CustomMemberInfo(field.Name, field.FieldType, field.GetValue(null)))
.ToArray();
CustomMemberInfo[] staticProperties = t
.GetProperties(BindingFlags.Public | BindingFlags.Static |BindingFlags.DeclaredOnly)
.Where(property => property != null && property.PropertyType.IsGenericParameter == false && property.GetValue(null) != null)
.Select(property => new CustomMemberInfo(property.Name, property.PropertyType, property.GetValue(null)))
.ToArray();
statics.AddRange(staticFields);
statics.AddRange(staticProperties);
}
}
string serializedStatics = JsonConvert.SerializeObject(statics, settings); // exception raised here
File.WriteAllText(Path.Combine(outputDirectory, "statics.json"), serializedStatics);
}
}
When I call this method I get a :
Newtonsoft.Json.JsonSerializationException: 'Error getting value from 'MetadataDispenser' on 'PostSharp.Serialization.SerializationReader+InstanceFields'.'
Inner exception : NullREferenceException: Object reference not set to an instance of an object
I imagine that a weird object is non serializable in the postsharp assembly and I would like to know how I can detect that in order to not add it to my CustomMemberInfo list.
Also, I use the postsharp WCF and NewtonSoft assemblies. I don't particularly want to save the static context in these assemblies but I don't see any criteria that will allow me to know that they do not directly belong in my solution. I can think of a solution using a whitelist of my assemblies name or a non-exhaustive blacklist of external assemblies (the white/black-list beeing read in a conf file).
EDIT : The null reference occurs in JsonConvert, not in my code. Here's the stackstrace :
at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract& memberContract, Object& memberValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
at Newtonsoft.Json.JsonConvert.SerializeObjectInternal(Object value, Type type, JsonSerializer jsonSerializer)
at Newtonsoft.Json.JsonConvert.SerializeObject(Object value, JsonSerializerSettings settings)
at WcfExceptionHandlingPocLib.Aspects.MethodBoundaryAspect.saveStaticCache(String outputDirectory, JsonSerializerSettings settings) in [..]\MethodBoundaryAspect.cs:line 174