Using InstancePerHttpRequest

1,102 views
Skip to first unread message

Dody Gunawinata

unread,
May 3, 2011, 1:43:13 PM5/3/11
to Autofac
I am trying to have a data store object to be created every
HttpRequest, so I use the InstancePerHttpRequest();

container.Register(c => new RavenStore(c.Resolve<DocumentStore>(),
c.Resolve<TenantIdentifier>().GetTenant().RavenName)).InstancePerHttpRequest();


Now I have a static method that's call multiple objects, which some
depend on the above instance

public static class DomainEvents
{
public static IContainer Container { get; set; } //as before

//Raises the given domain event
public static void Raise<T>(T args) where T : IDomainEvent
{
if (Container != null)
foreach (var handler in
Container.Resolve<IEnumerable<Handles<T>>>())
handler.Handle(args);
}
}

This generates the following error (truncated)


at Autofac.ResolutionExtensions.ResolveService(IComponentContext
context, Service service, IEnumerable`1 parameters)
at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext
context, IEnumerable`1 parameters)
at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext
context)
at SK.Framework.Toolkits.DomainEvents.Raise[T](T args) in G:
\Repository\Libre\Trunk\Lib\SK.Framework.Toolkits\DomainEvents.cs:line
20
at
Libre.Web.Areas.Admin.Controllers.TemplateController.Create(ShopTemplate
template, String section) in G:\Repository\Libre\Trunk\Libre.Web\Areas
\Admin\Controllers\TemplateController.cs:line 123


Now if I remove the InstancePerHttpRequest() method, everything works
just fine. Is there any way I can resolve this situation?

Nicholas Blumhardt

unread,
May 3, 2011, 6:14:09 PM5/3/11
to aut...@googlegroups.com
Dody, if you're using MVC3, resolve from DependencyResolver.Current. If not, use IContainerProvider.RequestLifetime.

Hope this helps, rushed reply so apologies if I missed the point :)

Nick

> --
> You received this message because you are subscribed to the Google Groups "Autofac" group.
> To post to this group, send email to aut...@googlegroups.com.
> To unsubscribe from this group, send email to autofac+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/autofac?hl=en.
>

Dody Gunawinata

unread,
May 4, 2011, 5:11:09 AM5/4/11
to aut...@googlegroups.com
I have fundamental problem in understanding the usage of autofac in
asp.net mvc that I'd like to get the bottom of. I've scoured through
the Internet for articles/resources on how to use it properly include
the codeproject article
(http://www.codeproject.com/KB/architecture/di-with-autofac.aspx).

I think my problem is I have no idea on how to configure deal with
InstancePerHttpRequest() scope.

So here's my general layout usually

1. Use ContainerBuilder to do container.Register all the classes
2. Then call container.Build()
3. Pass it to DependencyResolver.SetResolver(new
AutofacDependencyResolver(container)); in global.asax.cs

This is working fine and dandy since I use the default InstancePerDependency.

The trouble starts when I use InstancePerHttpRequest() in part one and
all hell break loose. Unfortunately all the examples I've seen about
asp.net mvc3 integration never use InstancePerHttpRequest() when they
register their classes.

This is what I tried after your suggestion

public static class DomainEvents
{
public static ILifetimeScope Container { get; set; } //as before

//Raises the given domain event
public static void Raise<T>(T args) where T : IDomainEvent
{
if (Container != null)
foreach (var handler in
Container.Resolve<IEnumerable<Handles<T>>>())
handler.Handle(args);
}
}


then in global.asax.cs Application_Start() method, I do

using (var scope = container.BeginLifetimeScope())
{
DomainEvents.Container = scope;
}


Now this throws

" Cannot access a disposed object.
Object name: 'Instances cannot be resolved and nested lifetimes cannot
be created from this LifetimeScope as it has already been disposed.'.
-- at Autofac.Core.Lifetime.LifetimeScope.CheckNotDisposed()"


I must be missing something stupid and obvious but I haven't been able
to finger where the problem is.

--
nomadlife.org

Nicholas Blumhardt

unread,
May 4, 2011, 6:12:16 AM5/4/11
to aut...@googlegroups.com
Hi Dody,

By using DependencyResolver.Current, I meant for resolving instances. Don't try keeping a 'container' reference around - e.g.:

 public static class DomainEvents
  {
      public static ILifetimeScope Container { get; set; } //as before

      //Raises the given domain event
      public static void Raise<T>(T args) where T : IDomainEvent
      {
          if (Container != null)
              foreach (var handler in DependencyResolver.Current.GetServices<Handles<T>>())
                  handler.Handle(args);
      }
  }

All you need to do in order for this to work is to set up AutofacDependencyResolver as you've already described.

Cheers,
Nick

Dody Gunawinata

unread,
May 4, 2011, 7:30:30 AM5/4/11
to aut...@googlegroups.com
OK this works. Thanks a lot.

Dody Gunawinata

unread,
May 4, 2011, 8:01:45 AM5/4/11
to aut...@googlegroups.com
Can a .SingleInstance() object consume an instance depending on
InstancePerHttpRequest?

I've try to wrap them via constructor using Lazy<> but it returns No
scope matching the expression,

--
nomadlife.org

Dody Gunawinata

unread,
May 4, 2011, 11:15:11 AM5/4/11
to aut...@googlegroups.com
I got it to work but I observe matching behaviour

builder.Register(c => new BlogValidator(() =>
DependencyResolver.Current.GetService<IDocumentStorage<Blog>>())).Keyed<IValidator>(typeof(Blog)).SingleInstance();

and

builder.Register(c => new
BlogValidator(c.Resolve<IDocumentStorage<Blog>>())).Keyed<IValidator>(typeof(Blog)).InstancePerLifetimeScope();

seems to behave the same way (I put a logger on BlogValidator
constructor) that BlogValidator is only created once in multiple
requests.

One of the dependency is an InstancePerHttpRequest().

So the SingleInstance() is supposed to behave this way. I don't
understand why InstancePerLifetimeScope() also behaves the same. Is it
a hanging reference?

--
nomadlife.org

Nicholas Blumhardt

unread,
May 4, 2011, 6:44:13 PM5/4/11
to aut...@googlegroups.com
Hi Dody,

Components with long lifetimes can never depend on components with short lifetimes - I think the problem here indicates your BlogValidator should not be SingleInstance().

Instead, if there really is state in the BlogValidator that must be shared between all components, extract that state into a third component that BlogValidator (non-SingleInstance()) can use, and mark that component as SingleInstance().

Cheers,
Nick

Dody Gunawinata

unread,
May 5, 2011, 3:55:17 AM5/5/11
to aut...@googlegroups.com
Can I get away doing this using Func<> such as

builder.Register(c => new BlogValidator(() =>
DependencyResolver.Current.GetService<IDocumentStorage<Blog>>())).Keyed<IValidator>(typeof(Blog)).SingleInstance();

On Thu, May 5, 2011 at 1:44 AM, Nicholas Blumhardt

Dody Gunawinata

unread,
May 5, 2011, 4:00:16 AM5/5/11
to aut...@googlegroups.com
My scenario is this, I am using a library called FluentValidator that
allows validation on forms. What it does is call the validator object
for every single field in the form.

So if I have 10 fields in my web form, FluentValidator try to retrieve
BlogValidator object ten times. Perhaps I should mark it with
InstancePerHttpRequest().

On Thu, May 5, 2011 at 10:55 AM, Dody Gunawinata

--
nomadlife.org

Matt Scully

unread,
Jun 10, 2011, 1:41:37 PM6/10/11
to Autofac
I'm replying to this thread because I have a similar issue in that I'm
trying to resolve an HttpRequest-scoped object from a Singleton.
However, in my case, the singleton is a custom ModelMetadataProvider
and so I can't make that to be scoped by HttpRequest even though it is
only ever called during an HttpRequest. I have tried injecting an
automatic factory in the constructor: public
MyModelMedataDataProvider(Func<HttpRequestBase> httpRequestFactory),
and then invoking the factory per request but that fails because it
can't find the "httpRequest" lifetime scope. Is there a reason this
doesn't work? I have been able to inject a Func<T> into a Singleton
when T was factory scoped per dependency, but this doesn't work for
PerHttpRequest scoping. It does work if I use
DependencyResolver.GetService(), but I would prefer not to take that
on as a dependency. Can Func<T> only be used to resolve factory-
scoped components?

--matt

On May 5, 3:00 am, Dody Gunawinata <empirebuil...@gmail.com> wrote:
> My scenario is this, I am using a library called FluentValidator that
> allows validation on forms. What it does is call the validator object
> for every single field in the form.
>
> So if I have 10 fields in my web form, FluentValidator try to retrieve
> BlogValidator object ten times. Perhaps I should mark it with
> InstancePerHttpRequest().
>
> On Thu, May 5, 2011 at 10:55 AM, Dody Gunawinata
>
>
>
>
>
>
>
> <empirebuil...@gmail.com> wrote:
> > Can I get away doing this using Func<> such as
>
> > builder.Register(c => new BlogValidator(() =>
> > DependencyResolver.Current.GetService<IDocumentStorage<Blog>>())).Keyed<IVa lidator>(typeof(Blog)).SingleInstance();
>
> > On Thu, May 5, 2011 at 1:44 AM, Nicholas Blumhardt
> > <nicholas.blumha...@gmail.com> wrote:
> >> Hi Dody,
> >> Components with long lifetimes can never depend on components with short
> >> lifetimes - I think the problem here indicates your BlogValidator should not
> >> be SingleInstance().
> >> Instead, if there really is state in the BlogValidator that must be shared
> >> between all components, extract that state into a third component that
> >> BlogValidator (non-SingleInstance()) can use, and mark that component as
> >> SingleInstance().
> >> Cheers,
> >> Nick
>
> >> On 5 May 2011 01:15, Dody Gunawinata <empirebuil...@gmail.com> wrote:
>
> >>> I got it to work but I observe matching behaviour
>
> >>> builder.Register(c => new BlogValidator(() =>
>
> >>> DependencyResolver.Current.GetService<IDocumentStorage<Blog>>())).Keyed<IVa lidator>(typeof(Blog)).SingleInstance();
>
> >>> and
>
> >>> builder.Register(c => new
>
> >>> BlogValidator(c.Resolve<IDocumentStorage<Blog>>())).Keyed<IValidator>(typeo f(Blog)).InstancePerLifetimeScope();
>
> >>> seems to behave the same way (I put a logger on BlogValidator
> >>> constructor) that BlogValidator is only created once in multiple
> >>> requests.
>
> >>> One of the dependency is an InstancePerHttpRequest().
>
> >>> So the SingleInstance() is supposed to behave this way. I don't
> >>> understand why InstancePerLifetimeScope() also behaves the same. Is it
> >>> a hanging reference?
>
> >>> On Wed, May 4, 2011 at 3:01 PM, Dody Gunawinata <empirebuil...@gmail.com>
> >>> >>>> > <empirebuil...@gmail.com>
> ...
>
> read more »

Nicholas Blumhardt

unread,
Jun 12, 2011, 6:13:35 PM6/12/11
to aut...@googlegroups.com
Hi Matt,

No, Funcs will only resolve components in the same scope as the component into which the Func is injected - they don't allow you to get around the rules that prevent long-lived components referencing short-lived ones.

In the current MVC3 integration I think the best option for you is to just use DependencyResolver.Current.GetService() to get hold of the per-request component from the Singleton.

Cheers,
Nick

Matt Scully

unread,
Jun 16, 2011, 11:24:56 AM6/16/11
to aut...@googlegroups.com
Hi Nick,

Thanks a lot for the response; this helps clear up my understanding a lot.  One last clarification that would help me understand how Autofac manages resources is how transient disposable objects get released when injected into a singleton as Func<TransientDisposableType>?  When I test, the object gets created each time the factory is invoked, but the objects are never disposed.  Based on your last message, I understand that this is because they were all created in the root lifetime scope and, therefore, will never get disposed.  Am I correct that this would be an anti-pattern in that it always results in a memory leak?

Thanks again,
--matt

Nicholas Blumhardt

unread,
Jun 16, 2011, 6:36:49 PM6/16/11
to aut...@googlegroups.com
Hi Matt,

Yes, that's correct. When using Autofac, dynamic instantiation should almost always happen in a nested scope with a finite lifetime.

Alternatively, your singleton can use Func<Owned<TransientDisposableType>> to take over ownership of the results from the container (creating an implicit scope around the TransientDisposableType instances.)

If you use Owned<T>, dispose the Owned<T> and not the T :)

Cheers,
Nick

--
You received this message because you are subscribed to the Google Groups "Autofac" group.
To view this discussion on the web visit https://groups.google.com/d/msg/autofac/-/tVdOe8Xe0zsJ.
Reply all
Reply to author
Forward
0 new messages