C# 当放入静态构造函数时,不会使用UnityContainer.RegisterType

C# 当放入静态构造函数时,不会使用UnityContainer.RegisterType,c#,.net,inversion-of-control,unity-container,C#,.net,Inversion Of Control,Unity Container,这是一个示例控制台应用程序(添加Unity NugGet软件包后运行良好),似乎显示Unity中存在错误: using System; using Microsoft.Practices.Unity; class GC { public static UnityContainer Container = new UnityContainer();} class Program { static void Main(string[] args) { GC.Con

这是一个示例控制台应用程序(添加Unity NugGet软件包后运行良好),似乎显示Unity中存在错误:

using System;
using Microsoft.Practices.Unity;

class GC { public static UnityContainer Container = new UnityContainer();}

class Program
{
    static void Main(string[] args)
    {
        GC.Container.RegisterType<MyView>();
        var myView = GC.Container.Resolve<MyView>();
        Console.ReadLine();
    }
}

public class MyClassDesign: MyClass{}
public class MyClass: VMBase<MyClass, MyClassDesign>{}
public abstract class VMBase<TViewModel, TDesignVM> where TDesignVM:TViewModel
{
    static VMBase()
    {
        if (!GC.Container.IsRegistered(typeof(TViewModel)))
            GC.Container.RegisterType(typeof (TViewModel), typeof(TDesignVM));
    }
}

public class MyView
{
    public MyView(MyClass myClass)
    {
        Console.WriteLine("Bad: "+myClass.GetType().ToString());
        Console.WriteLine("Good: "+GC.Container.Resolve<MyClass>().GetType());
    }
}
使用系统;
使用Microsoft.Practices.Unity;
类GC{public static UnityContainer Container=new UnityContainer();}
班级计划
{
静态void Main(字符串[]参数)
{
GC.Container.RegisterType();
var myView=GC.Container.Resolve();
Console.ReadLine();
}
}
公共类MyClassDesign:MyClass{}
公共类MyClass:VMBase{}
公共抽象类VMBase,其中TDesignVM:TViewModel
{
静态VMBase()
{
如果(!GC.Container.IsRegistered(typeof(TViewModel)))
RegisterType(typeof(TViewModel),typeof(TDesignVM));
}
}
公共类MyView
{
公共MyView(MyClass MyClass)
{
WriteLine(“错误:+myClass.GetType().ToString());
WriteLine(“好:+GC.Container.Resolve().GetType());
}
}
输出为:

坏:MyClass
好:我的班级设计

解析的类型是
MyClass
。但它应该是
MyClassDesign
。(静态构造函数在MyView类中解析MyClass之前运行。)

如何获得Unity以允许我在静态构造函数中设置映射?


注意:当我更改此设置时,带有文件的UnityContainer(而不是代码中的)一切正常。但我不希望依赖于外部文件来实现这一点。(我正在制作一个可重用的模板,我不想有太多的依赖项。)

为什么要将注册逻辑放在视图模型中?这会将应用程序代码耦合到容器中,这从来都不是一个好主意。请看一看的概念


DI容器的所有设置代码都应该放在那里。

为什么要将注册逻辑放在视图模型中?这会将应用程序代码耦合到容器中,这从来都不是一个好主意。请看一看的概念


DI容器的所有设置代码都应该放在那里。

这不是Unity的真正错误。问题是静态ctor在请求实例之前不会运行(此时unity仍然不知道
MyClassDesign
)。这意味着Unity已经开始创建
MyClass
的实例来满足请求。对
GC.Container.Resolve()的任何后续调用将产生您期望的输出。正如塞巴斯蒂安·韦伯(Sebastian Weber)所建议的,将所有设置代码放在一个完全独立的位置(这样您的类就不依赖于特定的DI容器)是最好的选择。

这并不是Unity的真正缺陷。问题是静态ctor在请求实例之前不会运行(此时unity仍然不知道
MyClassDesign
)。这意味着Unity已经开始创建
MyClass
的实例来满足请求。对
GC.Container.Resolve()的任何后续调用将产生您期望的输出。正如Sebastian Weber所建议的,将所有设置代码放在一个完全独立的位置(这样您的类就不依赖于特定的DI容器)是最好的选择