Should InstancePerRequest` work with Wcf integration?

426 views
Skip to first unread message

voss...@gmail.com

unread,
Jan 5, 2015, 10:30:30 AM1/5/15
to aut...@googlegroups.com
I unexpectedly found registrations using `InstancePerRequest` with Wcf Integration fail with:

> No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.

I was looking for this registration for the sake of having every resolution of the same type be the same instance when a service is resolved.


Considering the simplified (contrived) example,

```
int i = 0;
builder.Register<int>(c => i++);

builder.RegisterType<EchoService>();

// [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
// public class EchoService
// public EchoService(int i, int j){}
```

I want `i` and `j` to both be `0` the first time EchoService is created, (i, j) == (1,1) the next time and so on.

With `InstancePerDepenancy()` for the `int` registration we get: (0,1), (2,3), ...
With `SingleInstance()` for the `int` registration we get: (0,0), (0,0), ...
`InstancePerLifetimeScope()` does give the desired behavior: (0, 1), (2, 3), ...

As far as I know `InstancePerLifetimeScope()` will work for me, but it was not intuitive that per request wouldn't work and I needed to use per lifetime scope. I was also just looking to future proof: I do not currently do any custom work with lifetime scope but that is not to say I won't in the future.

I suppose the complication if `InstancePerRequest()` was implemented would be with InstanceContextMode.PerSession.

```
int i = 0;
builder.Register<int>(c => i++).InstancePerRequest();

builder.RegisterType<EchoService>();

// [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
// public class EchoService
// public EchoService(int i, Func<int> j)
```

Clearly `i` will be zero for the entire session, but what will `j()` be in the case of multiple requests? Is it possible recognize each call so it would increment, or should it be zero the entire session?

Travis Illig

unread,
Jan 5, 2015, 10:40:03 AM1/5/15
to aut...@googlegroups.com, voss...@gmail.com
InstancePerRequest doesn't work with WCF because the dependencies are injected with the service lifetime, not with a request lifetime. That is, if you have a singleton service that takes per-request dependencies, that won't work too well.

There is a note in the WCF integration documentation at the top addressing this (bold is actually in the docs): http://autofac.readthedocs.org/en/latest/integration/wcf.html

WCF integration provides dependency injection integration for services as well as client proxies.Due to WCF internals, there is no explicit support in WCF for per-request lifetime dependencies.

Sorry for any confusion.
-T
Reply all
Reply to author
Forward
0 new messages