2

这是一个示例控制台应用程序(在添加 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());
    }
}

输出是:

坏:MyClass
好:MyClassDesign

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

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

注意:当我使用文件(而不是代码)更改此设置时,UnityContainer 一切正常。但我宁愿不依赖外部文件。(我正在制作一个可重用的模板,我不想在其中包含太多依赖项。)

4

2 回答 2

0

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

于 2012-06-07T07:25:09.067 回答
0

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

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

于 2012-06-07T07:04:58.510 回答