views:

118

answers:

1

I've got an application where a shared object needs a reference to a per-request object.

Shared:      Engine
                |
Per Req:  IExtensions()
                |
             Request

If i try to inject the IExtensions directly into the constructor of Engine, even as Lazy(Of IExtension), I get a "No scope matching [Request] is visible from the scope in which the instance was requested." exception when it tries to instantiate each IExtension.

How can I create a HttpRequestScoped instance and then inject it into a shared instance?

Would it be considered good practice to set it in the Request's factory (and therefore inject Engine into RequestFactory)?

+1  A: 

Due to the shared lifetime requirements of Engine you cannot inject request-scoped extensions into it. What you could have is a method or property on Engine that will actively resolve a collection of extensions from the current request scope.

So first, let Engine take a constructor dependency:

public class Engine
{
    public Engine(..., Func<IExtensions> extensionsPerRequest) 
    {
        _extensionsPerRequest = extensionsPerRequest;
    }


    public IExtensions Extensions
    {
       get { return _extensionsPerRequest(); }
    }
 }

And then, in your Autofac registration:

builder.Register<Func<IExtensions>>(c => RequestContainer.Resolve<IExtensions>());
Peter Lillevold
Thank you very much for the solution.It took me a little fiddling to find out that in VB I needed to construct a function myself in the Register() call, but now it works :DThe lambda for the Autofac registration is: Function(c) New Func(Of IExtensions)(Function() RequestContainer.Resolve(Of IExtensions)())
Michael Wagner
Ah, cool. Glad to be of assistance!
Peter Lillevold