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

+3


source to share


2 answers


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.

+2


source


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.



+1


source







All Articles