Orchard CMS,Autofac关系

3
我正在尝试创建一个"A(UserManager) 需要创建 B(UserClient) 的实例"的关系(http://code.google.com/p/autofac/wiki/RelationshipTypes),其中B(UserClient)需要HttpSessionStateBase。
用户客户端
public class UserClient : IUserClient
    {
        public UserClient(HttpSessionStateBase session)
        {
             //...
        }

        //...
    }

用户管理器

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();
        }

这是注册Autofac的地方。
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>);
        }

我会尽力协助您进行翻译。以下是需要翻译的内容:

Autofac: 从 SingleInstance'd 类型到 HttpRequestScoped 的参考,它们使用了一些 RequestContainer,但我找不到这个东西。:)

错误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.

错误 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.

我已经尝试了将.InstancePerHttpRequest()切换为.InstancePerLifetimeScope(),以及其他许多不同的方法... 有人有什么想法吗?谢谢。
2个回答

3
在Orchard中手动添加Autofac注册时,如果需要单例,请使用InstancePerMatchingLifetimeScope("shell"),如果需要每个请求实例,请使用InstancePerMatchingLifetimeScope("work")
我不确定HttpSessionStateBase的构造函数参数是否可以从容器中解析。您可以将IHttpContextAccessor放置在那里,并在IUserClient实现中使用它来访问会话状态对象。
正如Jim Bolla建议的那样,Func<IUserClient>factory)已经可以直接使用。

啊,太好了。但是如果我将它更改为InstancePerMatchingLifetimeScope,我会得到“错误2”,但这次错误来自OrchardFramework.DLL!Orchard.ContentManager.DefaultContentManager.Handlers.get()内部。当我使用“AutofacWebTypesModule”时,HttpSessionStateBase不应该工作吗? - Fredrik Widerberg
使用IHttpContextAccessor并且没有AutofacWebTypesModule似乎工作正常.. 成功! - Fredrik Widerberg

1

我认为你不需要进行这两个注册。因为 关系类型 的缘故,Func<IUserClient> 应该已经对你可用。


你似乎是正确的!但是我仍然从“return userClientPerRequest();”这一行得到错误2。 - Fredrik Widerberg
我认为问题在于UserManager是SingleInstance,因此它及其依赖项将在Http上下文之外创建。 - Jim Bolla
即使我将UserManager设置为InstancePerHttpRequest,我仍会在创建UserManager时遇到相同的错误。但我认为UserManager可以是单个实例,因为它会为每个http请求创建一个新的UserClient?也许那不正确 :) - Fredrik Widerberg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接