0

ここで何かを誤解している可能性があるので、おそらくここに簡単な答えがあるかもしれませんが、現在頭を悩ませています。

IUnitOfWork を実装するクラス UnitOfWork があります (はいはい知っています)。作業単位のコンストラクターは IPrincipalFactory を取ります。TResponder は、IUnitOfWork を受け取るグラフのトップ レベルです。

ApplicationPrincipalFactory を有効期間スコープ内の特定のインスタンスとして登録しようとしています...これは、HandleAsync 関数に渡されるいくつかのプロパティに依存しています。私は次のことをしています:

    public async Task<TResponse> HandleAsync<TMessage, TResponse, TResponder>(TMessage message)
        where TMessage : class
        where TResponder : IRespondAsync<TMessage, TResponse>
    {
        using (var scope = this.BeginLifetimeScope(message))
        {
            var responder = scope.Resolve<TResponder>();
            return await responder.Respond(message);
        }
    }

    private ILifetimeScope BeginLifetimeScope<TMessage>(TMessage message)
    {
        var unwrapped = GetDomainContext(message);
        var applicationPrincipalFactory = this.CreateApplicationPrincipalFactory(unwrapped);

        var lifetime = this.container.BeginLifetimeScope(
            r => r.RegisterInstance(applicationPrincipalFactory).As<IPrincipalFactory>());

        return lifetime;
    }

    private ApplicationPrincipalFactory CreateApplicationPrincipalFactory(IDomainContext unwrapped)
    {
        var applicationPrincipalFactory =
            new ApplicationPrincipalFactory(
                unwrapped.Tenant,
                unwrapped.ActingTenant,
                unwrapped.Username);

        return applicationPrincipalFactory;
    }

私が読んだすべてに基づいて、 BeginLifetimeScope(r => 内で依存関係を定義すると、親コンテナーのバインディングがオーバーライドされるため、解決を呼び出すと、すべてがきちんと一緒にスロットされます。

ただし、例外があります。

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'Platform.Engine.Persistence.UnitOfWork' can be invoked with the available services and parameters: Cannot resolve parameter 'Platform.Engine.Security.IPrincipalFactory principalFactory' of constructor

このメソッド以外の場所に IPrincipalFactory を登録していません。IUnitOfWork は、外側のスコープで次のように定義されます。

builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();

また、有効期間ではなく外側のコンテナーに登録することで問題が発生した場合に備えて、子コンテナー内の unitofwork 登録を再定義しようとしました。

        var lifetime = this.container.BeginLifetimeScope(
            r => r.RegisterInstance(applicationPrincipalFactory).As<IPrincipalFactory>());

        var overrides = new ContainerBuilder();
        overrides.RegisterType<UnitOfWork>().As<IUnitOfWork>();
        overrides.Update(lifetime.ComponentRegistry);

        return lifetime;

何が欠けているのかわからない...アイデアや提案はありますか?

4

1 に答える 1

0

コンテナーの初期構成時に、ファクトリーを残りのタイプに登録します。

builder.RegisterType<ApplicationPrincipalFactory>().As<IPrincipalFactory>();

次に、ライフタイム スコープで、コンテキストを渡すことができるデリゲート ファクトリを解決します。

var factory = container.Resolve<Func<IDomainContext, IPrincipalFactory>>();
var instance = factory(context);

string署名に 3 つのパラメーターを追加することもできますFunc<>が、既に適切なコンテキスト オブジェクトがあるため、代わりにそれを渡します。

最後に、必要に応じてファクトリを使用します。

instance.DoesSomethingButNotSureWhat();

これにより、コンテキスト パラメーターを渡すためだけに有効期間スコープを更新する必要がなくなります。

于 2014-07-16T12:41:09.617 に答える