1

私のケースは非常に一般的ですが、答えが見つかりません。各セットアップでいくつかのサービスがモックされる統合テストがあります。これらのモックのコンストラクター インジェクションを取得するには、Autuofac コンテナーを更新する必要があります。基本的に、すべてのアプリケーション登録を含むメイン コンテナーがあり、テスト シナリオごとにオーバーライドされたサービスの子コンテナー/ライフタイム スコープを作成する必要があります。カスタム ILifetimeScopeProvider を登録しました

public class TestLifetimeScopeProvider : ILifetimeScopeProvider
{
    readonly ILifetimeScope container;
    private ILifetimeScope lifetimeScope = null;
    private ILifetimeScope testlifeScope = null;

    public TestLifetimeScopeProvider(ILifetimeScope container)
    {
        if (container == null) throw new ArgumentNullException("container");
        this.container = container;
    }

    public ILifetimeScope ApplicationContainer
    {
        get { return container; }
    }

    public ILifetimeScope GetLifetimeScope()
    {
        if (lifetimeScope == null)
        {
            lifetimeScope = ApplicationContainer.BeginLifetimeScope("AutofacWebRequest");
        }

        if (testlifeScope == null)
        {
            testlifeScope = lifetimeScope.BeginLifetimeScope("TestLifeScope");
        }

        return testlifeScope;
    }

    public ILifetimeScope GetLifetimeScope(Action<ContainerBuilder> configurationAction)
    {
        return GetLifetimeScope();
    }

    public void EndLifetimeScope()
    {
        if (lifetimeScope != null)
            lifetimeScope.Dispose();
    }

    public void EndTestLifetimeScope()
    {
        if (lifetimeScope != null)
        {
            testlifeScope.Disposer.Dispose();
            lifetimeScope = null;
        }
    }
}

静的コンストラクターから呼び出される

static TestBase()
    {
        var builder = new ContainerBuilder();
        DependencyRegistrar.Register(builder);

        Container = builder.Build();

        LsProvider = new TestLifetimeScopeProvider(Container);
        DependencyResolver.SetResolver(new AutofacDependencyResolver(Container, LsProvider));


    }

DependencyRegistrar.Register(ビルダー); すべての初期登録を保持

各テストセットアップに新しいモックを登録するいくつかのモック作成ロジックがあります

 builder.Register(c => mockInitializer.ServiceMock)
                            .As(mockInitializer.ServiceType)
                            .InstancePerMatchingLifetimeScope("TestLifeScope");
builder.Update(Container);

また、TearDownにロジックを配置しています

    [TearDown]
    public virtual void TearDown()
    {
        LsProvider.EndTestLifetimeScope();
    }

しかし、各テストの後に子スコープが破棄されたとしても、すべての登録はメインコンテナに残ります。したがって、サービスの実装をモックしてはならないテストを実行すると、このインターフェイスで以前のテストから登録されたモックが使用されます。

親クラスがテストを元に戻すためのトランザクションを作成するため、各テストセットアップでコンテナーを構築できないため、すべての IRepository インターフェイスなどを解決するために最初に実行される静的コンストラクターでコンテナーを構築する必要があります。

私も BeginLifetimeScope(c => ...) テクニックを試しましたが、成功しませんでした

誰かの考えはありますか?ありがとう

ps私はAutofac 3.0.1バージョンとMVC 4を使用しています

4

1 に答える 1