Orchard CMS, Autofac Relationship
I am trying to create "A (UserManager)" to instantiate the relationship B (UserClient) "( http://code.google.com/p/autofac/wiki/RelationshipTypes ) where B (UserClient) requires 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();
}
Here is the autofac stuff register
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: Link from SingleInstance'd type to HttpRequestScoped , they use some RequestContainer
, but I can't seem to find such a 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 tried to switch .InstancePerHttpRequest()
to .InstancePerLifetimeScope()
and whole other stuff. Does anyone have any idea?
thank
source to share
When adding Autofac registrations manually to Orchard, use InstancePerMatchingLifetimeScope("shell")
if you need a singleton or InstancePerMatchingLifetimeScope("work")
if you need an instance for each request.
I'm not sure if the HttpSessionStateBase
ctor argument can actually be resolved from the container. Instead, you can supply IHttpContextAccessor
and use it to access the session state object within the implementation IUserClient
.
And as Jim Ball suggested - Func<IUserClient>
( factory ) is already available out of the box.
source to share
I don't think you need to do one of these registrations. Due to the types of relationships , it Func<IUserClient>
should already be available to you.
source to share