5

型を登録してコンテナをセットアップするクラスと、注入したい静的プロパティを含むクラスの 2 つのクラスがあります。私の問題は、プロパティが注入によって設定されることはないため、メソッドを呼び出すと、プロパティは常に null になります。

public class ClassOne
{
    public void Method()
    {
        Container.RegisterType<IClass, ClassImplOne>("ImplOne");
        Container.RegisterType<IClass, ClassImplTwo>("ImplTwo");
    }
}

public static class ClassTwo
{
    [Dependency]
    public static IClass SomeProperty { get; set; }

    public static void SomeOtherMethod()
    {
        SomeProperty.AnotherMethod();
    }
}

Dependency 属性を削除し、ClassOne で簡単な操作を行うと、

ClassTwo.SomeProperty = Container.Resolve<IClass>("ImplOne");

それは正常に動作しますが、プロパティに値を明示的に割り当てずにこれを行うことができるかどうか (つまり、コンテナーが属性を介して注入できるかどうか) を知りたいですか?

編集:

ありがとう。ClassTwo から静的宣言を削除し、ClassOne に ClassTwo の RegisterType と Resolve を追加し、InjectionProperty も追加しました。

Container.RegisterType<IClass, ClassImplOne>("ImplOne", new InjectionProperty("SomeProperty"));

しかし、それでも機能しません:S

4

2 に答える 2

7

コメントを検討した後に編集:

Unity を介してすべてをカスケードする代わりに、静的クラスを使用したい、または使用する必要がある場合には、さまざまな理由があります。

静的クラスに、Unity 構成を介して構成可能/交換可能にしたい別のクラスへの依存関係がある場合、Unityで静的クラスの依存関係を解決する方法で説明されているように、ファクトリ パターンを使用することをお勧めします。または、静的クラス内からコンテナを参照するのではなく、必要に応じて依存関係を解決する関数を割り当てるだけです。利点の 1 つは、すべての Unity 構成を同じ場所に置くことができることです。

あなたの場合、次のようになります。

public static class ClassTwo
{
    private static IClass _someProperty;

    public static Func<IClass> ResolveProperty { private get; set; }

    private static IClass SomeProperty
    {
        get { return _someProperty ?? (_someProperty = ResolveProperty()); }
    }

    public static void SomeOtherMethod()
    {
        SomeProperty.AnotherMethod();
    }

}

そして、Unity 構成にこれを追加します。

ClassTwo.ResolveProperty = () => container.Resolve<IClass>();
于 2016-03-18T10:39:56.580 に答える
6

Unity は、クラスが Unity を介して解決されるときに依存関係を注入します。静的クラスを作成できないため、Unity は依存関係を注入できません。

Static クラスを持つ代わりに、Unity を使用してContainerControlledLifetimeManagerClassTwo の疑似シングルトン クラス ( ) を解決します。このように、Unity は が作成されたときに注入IClassし(Unity コンテナーを介して解決されます)、シングルトンとして構成されているため、アプリケーションのライフサイクル全体で常に同じインスタンスを保持します。ClassTwoClassTwoClassTwo

Unity を介して ClassTwo を解決する必要があります。

Container.RegisterType<IClass, ClassImplOne>("ImplOne");
Container.RegisterType<IClass, ClassImplTwo>("ImplTwo");
Container.RegisterType<InterfaceImplemetedByClassTwo, ClassTwo>();

//Simple example. Don't forget to use ContainerControlledLifetimeManager for ClassTwo to simulate sigleton.

ClassTwo が必要な場合:

Container.Resolve<InterfaceImplemetedByClassTwo>

ClassTwo で設定を行う:

public class ClassTwo : InterfaceImplemetedByClassTwo
{
    [Dependency("ImplOne")] //inject ClassImplOne
    public IClass SomeProperty { get; set; }

しかし、これは素晴らしい解決策ではありません。あなたの問題はDIの哲学にあると思います。アプリのトップ レイヤー クラスから依存関係をカスケードする必要があります。最上位層のクラスを明示的に解決します。( Container.Resolve) と依存関係の注入は、Unity の魔法のおかげでカスケードダウンします。2 つのクラス (トップ レイヤーかどうか) がClassTwoUnityの同じインスタンスを使用する必要がある場合ClassTwoContainerControlledLifetimeManager.

つまり、静的クラスは必要ありません。クラスの同じインスタンスを必要以上に他のクラスに注入します。

于 2013-02-28T12:11:00.867 に答える