Orchard CMS,Autofac关系

问题描述 投票:3回答:2

我正在尝试创建“ A(UserManager)需要创建B(UserClient)的实例”关系(http://code.google.com/p/autofac/wiki/RelationshipTypes),其中B(UserClient)需要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();
        }

这是注册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: Reference from a SingleInstance'd type to a 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()以及其他各种内容。有人有什么想法吗?

谢谢

c# inversion-of-control orchardcms autofac
2个回答
3
投票

在Orchard中手动添加Autofac注册时,如果需要单例,请使用InstancePerMatchingLifetimeScope("shell"),如果需要每个请求实例,请使用InstancePerMatchingLifetimeScope("work")

我不确定HttpSessionStateBase ctor参数是否可以从容器中解析出来。您可以将IHttpContextAccessor放在此处,并使用它来访问IUserClient实现中的会话状态对象。

而且正如Jim Bolla所建议-Func<IUserClient>factory)已经可以立即使用。


1
投票

我认为您不需要进行任何注册。由于Relationship TypesFunc<IUserClient>应该已经可以使用。


0
投票
//builder.Register(c => new CassandraAccess(c.Resolve<NLog.ILogger>(),
            //    c.Resolve<IEStatementConfigurationProvider>().GetCassandraSettingConfiguration())).As<ICassandraAccess>();
            //
            //.WithParameter("cassandraSettings", );
            builder.RegisterType<CassandraAccess>().As<ICassandraAccess>()
                .WithParameter("cassandraSettings", GetCassandraSettingFromConfig(configuration));



            //builder.Register(c => new CassandraAccess(c.Resolve<NLog.ILogger>(),
            //    c.Resolve<IEStatementConfigurationProvider>().GetCassandraSettingConfiguration()
            //    )).As<ICassandraAccess>();

            //builder.Register(c =>
            //    new BaasConfigCassandraRepository(c.Resolve<NLog.ILogger>(),
            //        c.Resolve<ICassandraAccess>())).As<IBaasConfigRepository>();

            builder.RegisterType<BaasConfigCassandraRepository>().As<IBaasConfigRepository>();
            //    .WithParameter("logger", NLog.LogManager.GetCurrentClassLogger());
            //.WithParameter("cassandraAccess",);()
            //builder.RegisterType<BaasConfiguration>().As<IBaasConfiguration>()
            //    .WithParameter("logManager",)
            //    .WithParameter("configName", "BaasConfigData");

            //Lazy DI
            //builder.Register(c => new BaasConfiguration(GetLazy<IBaasConfigRepository>(c), c.Resolve<ILogManager>(), "BaasConfigData")).Named<IBaasConfiguration>("BaasConfig");

            builder.RegisterType<BaasConfiguration>().As<IBaasConfiguration>()
                .WithParameter("configName", "BaasConfigData")
            .Named<IBaasConfiguration>("BaasConfig");

            //builder.RegisterType<BaasLocalConfiguration>().As<IBaasConfiguration>().Named<IBaasConfiguration>("BaasLocalConfig");

            builder.Register(c => new BaasLocalConfiguration()).Named<IBaasConfiguration>("BaasLocalConfig");


 private static Lazy<T> GetLazy<T>(IComponentContext component)
        {
            var context = component.Resolve<IComponentContext>(); // must be 
            return  new Lazy<T>(context.Resolve<T>);
        }
© www.soinside.com 2019 - 2024. All rights reserved.