I've also noticed that I get quite a few hits, but little or no comments. Well, I like comments, they tell me if I am going in the right direction, or if I've forgotten something, or better yet, if someone has a better idea that I can snatch. So please, feel free to comment, or ask questions, I am more than happy to answer them. In fact, there is nothing quite like a good comment which points out an error, or suggests an alternative path, to wake up the mind.
Well, as you may recall last time, we had in our testing code a function which would return a NetworkFormatter. As I recall, it went something like the following:
Quote:private NetworkFormatter GetFormatter() { System.Reflection.Assembly sharedAssembly = typeof(Kent.Shared.Vector).Assembly; NetworkFormatter formatter = new NetworkFormatter(sharedAssembly); Assert.IsNotNull(formatter); return formatter;}
This code has a minor problem with it. Specifically, it ties our formatting tests to our shared library, a dependancy that we don't need. So, lets add an object to our tests, we'll call it SerializableObject, it shall contain an integer and a string. For now this will do as a simple test object. We also shall change the above function to match the new code:
Quote:private NetworkFormatter GetFormatter() { System.Reflection.Assembly sharedAssembly = typeof(SerializableObject).Assembly; NetworkFormatter formatter = new NetworkFormatter(sharedAssembly); Assert.IsNotNull(formatter); return formatter;}
Quote:namespace Kent.Serialization.Network.Tests { [Serializable] public struct SerializableObject { public SerializableObject(int value, string name) { this.Value = value; this.Name = name; } public int Value; public string Name; }}
This removed our need to depend on the shared assembly. Problem sovled [grin].
We can successfully enumerate the serializable types in our assembly, so the next step should be assigning IDs to the types. The best choice it would appear, at this point in time, would be to use the array index. Thus the first object should be our SerializableObject, so lets test this assumption:
Quote:[Test]public void GetTypeIDTest() { NetworkFormatter formatter = GetFormatter(); Type[] types = formatter.GetSerializableTypes(); Assert.AreEqual(types[0], typeof(SerializableObject), "Expected the first entry to be SerializableObject");}
Running our tests, we see that this is indeed the case. However, we really should be able to wrap this up in a method which, when passed an ID, will give the type. To do this we will need to add a member to the NetworkFormatter, and ensure that GetSerializableTypes is called before the new method.
Quote:public NetworkFormatter(Assembly sharedAssembly) { this.sharedAssembly = sharedAssembly; serializableTypes = GetSerializableTypes();}private Type[] serializableTypes;
Now we can add our new method, called GetTypeFromId:
Quote:internal Type GetTypeFromId(int id) { try { return serializableTypes[id]; } catch (IndexOutOfRangeException) { throw new SerializationException("Type not found for ID: " + id); }}
Next we should refactor our test to use this new method, which is easy enough to do:
Quote:[Test]public void GetTypeIDTest() { NetworkFormatter formatter = GetFormatter(); Assert.AreEqual(formatter.GetTypeFromId(0), typeof(SerializableObject), "Expected the first entry to be SerializableObject");}
Now we have to find some way of querying the ID of a type. The simplest way to do this is to map Types to integers, using a Dictionary object. But first, the test.
Quote:[Test]public void GetIdFromTypeTest() { NetworkFormatter formatter = GetFormatter(); Dictionary typeIdMap = new Dictionary(); Type[] serializableTypes = formatter.GetSerializableTypes(); for (int i = 0; i < serializableTypes.Length; ++i) { typeIdMap.Add(serializableTypes[0], i); } int id = typeIdMap[typeof(SerializableObject)]; Assert.IsTrue(id == 0, "Expected the ID of SerializableObject to be 0, found {0}", id);}
Simple enough, it just loops through each type and adds it to the map, along with it's associated ID. However, this really belongs as a few methods under the NetworkFormatter, so first lets add a GetTypeIdMap(), We should also alter our test to be in terms of this new method.
Quote:public NetworkFormatter(Assembly sharedAssembly) { this.sharedAssembly = sharedAssembly; serializableTypes = GetSerializableTypes(); typeIdMap = GetTypeIdMap();}internal Dictionary GetTypeIdMap() { Dictionary typeIdMap = new Dictionary(); Type[] types = GetSerializableTypes(); int id = 0; foreach (Type t in types) { typeIdMap.Add(t, id); ++id; } return typeIdMap;}private Dictionary typeIdMap;
Quote:[Test]public void GetIdFromTypeTest() { NetworkFormatter formatter = GetFormatter(); Dictionary typeIdMap = formatter.GetTypeIdMap(); int id = typeIdMap[typeof(SerializableObject)]; Assert.IsTrue(id == 0, "Expected the ID of SerializableObject to be 0, found {0}", id);}
That's about all for now. Next time we'll look at some refactorings that need to be done to the NetworkFormatter.
Well, here's your meaningless post..... I find I read other people's journals if they have posted on my journal in the recent past (subtle hint). It's kind of a hard method though as there are just so many now.