I am trying to create a "A(UserManager) needs to create instances of B(UserClient)" relationship (http://code.google.com/p/autofac/wiki/RelationshipTypes) where B(UserClient) needs a HttpSessionStateBase..
UserClient
public class UserClient : IUserClient
{
public UserClient(HttpSessionStateBase session)
{
//...
}
//...
}
UserManager
public class UserManager : IUserManager
{
private readonly Func<IUserClient> userClientPerRequest;
private IUserClient UserClient
{
get
{
return userClientPerRequest();
}
}
public UserManager(Func<IUserClient> userClientPerRequest)
{
this.userClientPerRequest = userClientPerRequest;
}
public void DoStuff()
{
UserClient.DoStuff();
}
This is where is register autofac stuff
public class MyModule : Module
{
protected override void Load(ContainerBuilder builder)
{
base.Load(builder);
builder.RegisterType<UserManager>().As<IUserManager>().SingleInstance();
builder.RegisterType<UserClient>().As<IUserClient>().InstancePerHttpRequest();
builder.RegisterModule(new AutofacWebTypesModule());
//If i try this, i get Error 1 (printing errors after this code-block)
builder.Register<Func<IUserClient>>(c => c.Resolve<IUserClient>);
//If i try this, i get Error 2
builder.Register<Func<IUserClient>>(c => {
var ctx = c.Resolve<IComponentContext>();
return ctx.Resolve<IUserClient>;
});
//If i try this, well i always get null from GetService..
builder.Register<Func<IUserClient>>(c =>
DependencyResolver.Current.GetService<IUserClient>);
}
Looking at Autofac: Reference from a SingleInstance'd type to a HttpRequestScoped , they use some RequestContainer
but i can find no such thing. :)
Error 1
This resolve operation has already ended. When registering components using lambdas, the IComponentContext 'c' parameter to the lambda cannot be stored. Instead, either resolve IComponentContext again from 'c', or resolve a Func<> based factory to create subsequent components from.
Error 2
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 reqested 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 have tried switching .InstancePerHttpRequest()
to .InstancePerLifetimeScope()
and a whole other different stuff.. Anyone have any ideas?
Thanks
When adding Autofac registrations manually in Orchard, use InstancePerMatchingLifetimeScope("shell")
, if you need a singleton or InstancePerMatchingLifetimeScope("work")
, if you need per-request instance.
I'm not sure if HttpSessionStateBase
ctor argument can actually be resolved from the container. You could put IHttpContextAccessor
there instead and use it to access the session state object inside IUserClient
implementation.
And as Jim Bolla suggested - Func<IUserClient>
(factory) is already available out of the box.