I'm testing legacy code with Microsoft Fakes and some shims. To test concurrency in the access of a shared resource I had to create some AppDomains to which I pass a fixture with their context. This couldn't be done only with threads because shims aren't thread safe. I expect also that on returning that context to the main AppDomain I can use that data for the tests expectations.
One of the properties of my fixture is a Dictionary that I update inside my shims for the legacy code. The problem I'm having is that I can't update the value for the dictionary.
In this method I shim a static class that would write to the registry:
public static void ShimRegistry(PlafondManagerTestFixtureUser fixture)
{
Common.Util.Fakes.ShimRegistryHelper.SetLocalMachineRegistrySettingStringStringString = (parent, key, value) => {
if (fixture.Registries != null)
{
var quant = Decrypt(value);
if (fixture.Registries.ContainsKey(key))
fixture.Registries[key] = quant;
else
fixture.Registries.Add(key, quant);
}
return null;
};
Common.Util.Fakes.ShimRegistryHelper.GetLocalMachineRegistrySettingStringStringString = (parent, key, value) => {
string val;
fixture.Registries.TryGetValue(key, out val);
return Encrypt(val);
};
}
When I debug this I can see that before
fixture.Registries[key] = quant;
I have "0" as the value of the dictionary entry and "2" in quant
.
Immediately after running that line the dictionary entry still reads "0".
I'm stuck with this and I couldn't find similar issues on stack overflow (or maybe I'm not finding the right words to describe it).
Other parts of this setup work fine. I can receive an updated string on the main thread, so I doubt that this has anything to do with me sharing instances between AppDomains.
Can anybody help me find whats wrong?
Updated: As Jon Skeet suggested, I tested this outside of the context of mstest, appdomain, shims and even right before the faulty code. In every case it's working as expected, so it might have something to do with sharing a dictionary between AppDomains in the fixture.
This is what I used to test:
Dictionary<string, string> test = new Dictionary<string, string>
{
{ "Key", "Value" }
};
test["Key"] = "Value2";
I have that feeling that I'm missing some stupid little thing, but just can't seem to find what it is.
Update 2: Managed to reduce the problem to passing the dictionary to another AppDomain.
Here's a sample console project I put on Github;
Update 3: Now that I had something more specific to search for I found this answer that helped me:Adam Ralph's answer to 'Sharing data between AppDomains'
I'll bet on serialization to string as I already have a way to do it easily, but still would like to understand why this happens the way it does.