StructureMap 和逻辑调用上下文

StructureMap and logical call contexts

我有一个关于 StructureMap 的特殊问题。

每当我构造一个生成新线程的对象时,逻辑调用上下文 (System.Runtime.Remoting.Messaging.CallContext) 就会变为空:

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")}");
        }
    }
}

以上代码给出了这些结果:

   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 

如您所见,当在构造函数(或在构造函数中生成的线程)中访问逻辑调用上下文时,它不适用于 StructureMap。

有人知道为什么吗?

您在调用 CallContext.LogicalSetData

之前创建了 PersistedObject 的实例
Container c = new Container(map =>
{
    map.For<PersistedObject>().Use(new PersistedObject()); // <-- This is calling the ctor.
});

CallContext.LogicalSetData("myvar", "Logical call context variable");

如果将上面的代码改成

Container c = new Container(map =>
{
    map.For<PersistedObject>().Use<PersistedObject>(); // <-- No ctor call
});

CallContext.LogicalSetData("myvar", "Logical call context variable");

你应该得到正确的输出。