Decorator for creating Scope with ScopedLifestyle.Flowing in Simple Injector

The problem is caused by the mixture of both flowing/closure scoping vs ambient scoping. Since you are writing a WPF application, you choose to use Simple Injector’s Flowing scopes feature. This allows you to resolve instances directly from a scope (e.g. calling Scope.GetInstnace).

This, however, doesn’t mix with Ambient Scoping, as is what AsyncScopedLifestyle.BeginScope does.

To fix this, you will have to change the implementation of your decorator to the following:

public class TransactionDatabaseCommandDecorator 
    : IDatabaseCommand<DatabaseResult, BusinessCommandParams1>
{
    private readonly Container _container;
    private readonly Func<IDatabaseCommand<DatabaseResult, BusinessCommandParams1>>
        _decorateeFactory;

    public TransactionDatabaseCommandDecorator(
        Container container,
        Func<IDatabaseCommand<DatabaseResult, BusinessCommandParams1>> decorateeFactory)
    {
        _container = container;
        _decorateeFactory = decorateeFactory;
    }

    public DatabaseResult Execute(BusinessCommandParams1 commandParam)
    {
        DatabaseResult res;
        using (Scope scope = new Scope(_container))
        {
            var command = _decorateeFactory.Invoke(scope);

            var factory = scope
                .GetInstance<IDesignTimeDbContextFactory<WpfRadDispenserDbContext>>();

            ...
        }

        return res;
    }
}

Note the following about the decorator above:

  • It gets injected with a Func<Scope, T> factory. This factory will create the decoratee using the provided Scope.
  • The execute method now creates a new Scope using new Scope(Container) instead of relying on the ambient scoping of AsyncScopedLifestyle.
  • The Func<Scope, T> factory is provided with the created scope.
  • The IDesignTimeDbContextFactory<T> is resolved from the Scope instance, instead of using the Container.

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top