Reputation: 75
I have a peculiar problem with StructureMap.
Whenever I construct an object, that spawns a new thread, the logical Call context (System.Runtime.Remoting.Messaging.CallContext
) becomes empty:
class Program
{
static void Main(string[] args)
{
Container c = new Container(map =>
{
map.For<PersistedObject>().Use(new PersistedObject());
});
CallContext.LogicalSetData("myvar", "Logical call context variable");
Console.WriteLine($"Main: {Thread.CurrentThread.ManagedThreadId}: {CallContext.LogicalGetData("myvar")}");
var obj = c.GetInstance<PersistedObject>();
obj.Print("IoC");
Console.WriteLine("--------------------");
new PersistedObject().Print("Constructed");
Console.ReadLine();
}
public class PersistedObject
{
public PersistedObject()
{
Console.WriteLine($"Ctor: {Thread.CurrentThread.ManagedThreadId}: {CallContext.LogicalGetData("myvar")}");
Thread t = new Thread(() => Print("Thread"));
t.Start();
}
public void Print(string message)
{
Console.WriteLine($"{message}: {Thread.CurrentThread.ManagedThreadId}: {CallContext.LogicalGetData("myvar")}");
}
}
}
The above code gives these results:
Main: 10: Logical call context variable
Ctor: 10: <Null>
Thread: 11: <Null>
IoC: 10: Logical call context variable
--------------
Ctor: 10: Logical call context variable
Constructed: 10: Logical call context variable
Thread: 12: Logical call context variable
As you can see, when the logical call context is accessed in the constructor (or the thread that is spawned in the constructor), it doesn't work with StructureMap.
Anyone have an idea about why?
Upvotes: 0
Views: 126
Reputation: 18112
You're creating an instance of PersistedObject
before the call to CallContext.LogicalSetData
Container c = new Container(map =>
{
map.For<PersistedObject>().Use(new PersistedObject()); // <-- This is calling the ctor.
});
CallContext.LogicalSetData("myvar", "Logical call context variable");
If you change the code above to
Container c = new Container(map =>
{
map.For<PersistedObject>().Use<PersistedObject>(); // <-- No ctor call
});
CallContext.LogicalSetData("myvar", "Logical call context variable");
You should get the correct output.
Upvotes: 1