5

循環参照に関するautofacwikiページは、以下を使用すると述べています。

cb.Register<DependsByProp>().OnActivated(ActivatedHandler.InjectUnsetProperties);

しかし、ActivatedHandlerは2.4.5ではもう存在しないようです。ソースを調べてみると、そのクラスの実装が見つかったので、代わりにOnActivatedにメソッドの実装を入れました。残念ながら、これはまだ機能しません。

ここに、Wikiページにあるような最小限の再現をまとめました。

class M
{
    public VM VM { get; set; }

    public M()
    {
    }
}

class VM
{
    public VM(M m)
    {
    }
}

[Fact]
void CanResolveCircular()
{
    ContainerBuilder builder = new ContainerBuilder();

    builder.RegisterType<VM>();
    builder.RegisterType<M>().OnActivated(e => e.Context.InjectUnsetProperties(e.Instance));

    using (var container = builder.Build())
    {
        var m = container.Resolve<M>();
        Assert.NotNull(m);
    }
}

Resolveが試行されると、このコードはスタックオーバーフロー例外をスローします。私は何が欠けていますか?Autofacに循環依存を処理させる正しい方法は何ですか?

4

2 に答える 2

7

循環依存に関するAutofacのドキュメントには次のように記載されています。

両方のクラスがFactoryスコープに登録されている場合、このシナリオを設定することは意味がないことに注意してください。

あなたMVM登録の両方がInstancePerDependency(以前はとして知られていましたFactoryScope)なので、このステートメントはあなたのシナリオに適用されます。その結果、MインスタンスとVMインスタンスを作成するという無限ループに陥ります。

注入されたプロパティが解決したものと同じインスタンスVM取得するようにする場合は、の存続期間を(eg )以外に変更する必要があります。これを以下に示します。MMInstancePerDependencySingleInstance

builder.RegisterType<M>().PropertiesAutowired(true).SingleInstance();

注:最近のPropertiesAutowired(true)拡張メソッドも使用しています。これは、再現のOnActivatedコードの代わりに使用できます。

Mアプリごとに1つのインスタンスが必要ない場合は、を設定しLifetimeScopeて使用できますInstancePerLifetimeScope

于 2011-05-31T13:19:01.560 に答える
5

ここに興味がある人にとっては、これを行う新しい方法です。

class DependsByProp1
{
    public DependsByProp2 Dependency { get; set; }
}

class DependsByProp2
{
    public DependsByProp1 Dependency { get; set; }
}

// ...

var cb = new ContainerBuilder();
cb.RegisterType<DependsByProp1>()
      .InstancePerLifetimeScope()
      .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);
cb.RegisterType<DependsByProp2>()
      .InstancePerLifetimeScope()
      .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);

プロパティ/プロパティの依存関係

于 2014-05-03T15:01:54.303 に答える