结构化映射和逻辑调用上下文

本文关键字:调用 上下文 映射 结构化 | 更新日期: 2023-09-27 18:28:20

我对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");

您应该得到正确的输出。