Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add information about working in applications that lack Ambient Context #44

Closed
dotnetjunkie opened this issue Aug 15, 2016 · 1 comment

Comments

@dotnetjunkie
Copy link
Collaborator

dotnetjunkie commented Aug 15, 2016

A typical way of working with Simple Injector in Ambient Context-lacking applications (Read: Windows RT) is the following:

// Starting/ending scopes
using (var scope = new Scope(container))
{
    // Attach runtime data to the scope to allow it to flow through the graph
    scope.SetItem("requestId", Guid.NewGuid());

    // Resolve directly from the scope:
    var service = scope.GetInstance<IMyService>();
    await service.DoYourThing();
}

// Using scopes
public class CommandDispatcher : ICommandDispatcher
{
    private readonly Scope scope;
    public CommandDispatcher(Scope scope) {
        this.scope = scope;
    }

    public void Dispatch<T>(T command) {
        // Services should again be resolved from the scope to continue flowing runtime data.
        var handler = this.scope.GetInstance<ICommandHandler<T>>();

        handler.Handle(new CommandEnvelope<T>(
            // Runtime data can be retrieved from the Scope again by injecting it into an adapter:
            requestId: (Guid)this.scope.GetItem("requestId"),
            command: command));
    }
}

The previous code enables flowing runtime data; in case components must be registered as scoped, a custom scoped lifestyle must be created (since Simple Injector doesn't have anything for this in the box):

sealed class NonAmbientScopedLifestyle : ScopedLifestyle
{
    public NonAmbientScopedLifestyle() : base("Non-ambient Scoped") { }

    protected override Func<Scope> CreateCurrentScopeProvider(Container c) {
        return ThrowNotSupported;
    }

    [DebuggerStepThrough] private static Scope ThrowNotSupported()  {
        throw new NotSupportedException("You can't resolve directly from the container.");
    }
}

// Registration
var container = new Container();
container.Options.DefaultScopedLifestyle = new NonAmbientScopedLifestyle();

container.Register<IUserContext, UserContext>(Lifestyle.Scoped);
@dotnetjunkie
Copy link
Collaborator Author

Feature will be removed from v4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant