1

私はUnityを使い始めようとしていますが、この特定の問題について助けを求めています。依存性注入/ Unityとは何か、プログラムでこれを行う方法はすでに理解していますが、メンバーがいつどのように入力されるかはわかりません。 Dependency-Attributeでマークされています。

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内のコメントされていないセクションは正常に機能します。ただし、属性「依存関係」を使用すると、プロパティは設定されません。ユニティコンテナへの呼び出しがありませんか?ご協力ありがとうございました。

スティーブのアドバイスによると、静的クラスの代わりにインスタンスを使用して、例を変更しました。

 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は代わりに解決された依存関係を持つ既知のタイプのプログラムをプログラムコードで返すべきではありませんか?Webで見つけた例では、常にこのようなコンストラクターインジェクションを使用しています

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

私はついにインジェクションコンストラクターのサンプルに問題があることを発見しました。もちろん、コンストラクターはPUBLICである必要があります。例外メッセージは私を少し混乱させました。

4

1 に答える 1

7

いくつかのポイント:

  • 現在、コンテナをXMLで完全に構成しているようです。そうしないでください!XMLでビルド(デプロイメント構成)した後に実際に変更できる依存関係のみを構成する必要があります。XMLベースの構成は非常に脆弱であり、コンパイル時のサポートがなく、インテリセンスのサポートがなく、表現力に欠けるため、残りの部分については、コードベースの構成を使用してください。
  • コンポーネントの初期化にメソッドインジェクションを使用しないでください。これは時間的結合につながります。依存性を注入する主な方法は、コンストラクター注入を使用することです。コンストラクターパラメーターへのすべての依存関係を定義します。依存関係を持つすべての型には、必要なすべての依存関係を含む単一のパブリックコンストラクターが必要です。Unityはそのコンストラクターを自動的に検出し、そのコンストラクターを呼び出して依存関係を挿入する方法を認識します。
  • 属性はまったく使用しないでください。これにより、コードが使用されるコンテナーに結合されますが、アプリケーションコードはDIコンテナーの存在を認識しないはずです。繰り返しますが、コンストラクターインジェクションに固執します。
于 2012-06-01T09:43:22.277 に答える