用于静态成员的Unity DI(例如在静态类程序中)/何时填充成员

时间:2012-06-01 09:29:28

标签: dependency-injection unity-container enterprise-library

我正在努力开始团结,我正在寻找这个特殊问题的帮助: 我已经了解了依赖注入/统一是什么以及如何以编程方式执行此操作但我不明白当成员使用依赖项属性标记时如何/何时填充。

class Program
{
    static Program()        
    {
        uContainer = new UnityContainer();
        var section =   (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
        section.Configure(uContainer);
    }

    private static IUnityContainer uContainer;

    [InjectionMethod]
    public static void InjectTrace(ITraceManager traceManager)
    {
        trace = traceManager;
    }

    [Dependency]
    public static ITraceManager trace { get; set; }// = /*new WebTraceManager("C:\\","trace",true);//*/new EnterpriseLibaryLoggingWrapper(false);

    static void Main(string[] args)
    {
        //Programmatically inject dependency
        // TODO: Do this via attributes
        //UnityContainer myContainer = new UnityContainer();
        //UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

        //section.Containers["containerOne"].Configure(myContainer);
        //trace = myContainer.Resolve<ITraceManager>();
        trace.ProgramStatus("Start");
        trace.ProgramStatus("End");
        Console.ReadLine();
    }
}

Main中以编程方式设置trace属性的未注释部分正常工作。但是使用属性“Dependency”将不会填充该属性。 是否缺少对统一容器的调用? 谢谢你的帮助。

根据Steve的建议,我改变了示例,使用实例而不是静态类:

 static Program()
    {
        uContainer = new UnityContainer();
        var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
        section.Configure(uContainer);
        Instance = uContainer.Resolve<Program>();
    }

    Program(ITraceManager traceManager)
    {
        trace = traceManager;
    }

    static readonly Program Instance;

    //Do not use Dependency Attribute
    //[Dependency]
    public  ITraceManager trace { get; set; }// = /*new WebTraceManager("C:\\","trace",true);//*/new EnterpriseLibaryLoggingWrapper(false);

    static void Main(string[] args)
    {          
        Instance.Run();
    }

    void Run()
    {            
        trace.ProgramStatus("Start");
        trace.ProgramStatus("End");
        Console.ReadLine();
    }

但是在打电话时

Instance = uContainer.Resolve<Program>();

,我接到一个例外,告诉我,该程序未在容器中注册。这是真的,但不应该 Unity通过已知类型的程序代码返回已解决的依赖项而不是? 我在网上找到的例子总是像这样使用构造函数注入

IUnityContainer uContainer = new UnityContainer();
MyObject myInstance = uContainer.Resolve<MyObject>();

我终于发现了注入构造函数示例的问题,当然构造函数必须是PUBLIC。异常消息让我有点困惑。

1 个答案:

答案 0 :(得分:7)

几点:

  • 您目前似乎在XML中完全配置容器。 不要这样做!您应该只配置在XML中构建(部署配置)后实际可以更改的依赖项。其余的,使用基于代码的配置,因为基于XML的配置非常脆弱,缺乏编译时支持,缺乏智能支持,缺乏表达能力。
  • 不要使用方法注入来初始化组件。这导致Temporal Coupling。注入依赖项的主要方法是使用构造函数注入。定义构造函数参数的所有依赖项。所有具有依赖项的类型都应该包含single public constructor,其中包含所有必需的依赖项。 Unity将自动找到该构造函数,并知道如何调用该构造函数并注入依赖项。
  • 根本不使用属性!这会将您的代码耦合到所使用的容器,而应用程序代码应该忽略DI Container的存在。再次,坚持使用构造函数注入。