MVC3中的Ninject会话范围概念

Min*_*ing 8 c# asp.net-mvc ninject

我正在使用Ninject框架构建MVC3应用程序.我有一个耗时的服务初始化,最后这个服务将有一个包含用户特定信息的对象,然后我需要重新使用该服务,只要用户会话是活动的,这样我可以避免一次又一次地初始化该服务

所以我的问题是

当我使用Ninject绑定服务时,我应该选择哪种范围,Ninject中的每个范围都没有会话,那么实现该要求的最佳方法是什么?还是我走错了方向?

我已经为我的一个服务创建了一个自定义提供程序,它将根据从当前Controller.User.Identity.Name中获取的用户名详细信息创建服务.下面的代码不起作用,因为缺少userName局部变量,如何通过Ninject将用户名值传递给我的自定义提供程序,以便我可以从IContext中获取它?

public class TfsConnectionManagerProvider : Provider<TfsConnectionManager>
    {
        protected override TfsConnectionManager CreateInstance(IContext context)
        {
            Uri serverUri = new Uri(ConfigurationHelper.TfsServerUrl);
            // Connect to the server without impersonation
            using (TfsTeamProjectCollection baseUserConnection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(serverUri))
            {
                // Get the identity management service
                IIdentityManagementService ims = baseUserConnection.GetService<IIdentityManagementService>();

                // Get the identity to impersonate
                TeamFoundationIdentity identity = ims.ReadIdentity
                (
                    IdentitySearchFactor.AccountName,
                    userName,  //NOTE: How can I get user name value from IContext???
                    MembershipQuery.None,
                    ReadIdentityOptions.None
                );

                // Connect using the impersonated identity
                using (TfsTeamProjectCollection impersonatedConnection = new TfsTeamProjectCollection(serverUri, identity.Descriptor))
                {
                    WorkItemStore store = impersonatedConnection.GetService<WorkItemStore>();

                    return new TfsConnectionManager
                    {
                        Store = store
                    };
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

Rem*_*oor 7

Ninject中故意不提供会话范围,因为在几乎所有情况下,会话状态中的服务都是错误的.您应该非常小心地使用会话状态,因为它带来了很多缺点.

尝试首先使用无状态应用程序.

如果有足够的理由在会话范围中包含数据,那么将该数据(而不是服务)放入会话状态,并使用单例,瞬态或请求范围内的服务进行处理(数据和功能的分离).


Min*_*ing 2

我结果使用自定义提供程序来创建实例,并在自定义提供程序中检查它是否存在于会话中。

绑定完成如下

Bind<IRepository>().ToProvider(new TfsRepositoryProvider());
Run Code Online (Sandbox Code Playgroud)

自定义Provider如下

public class TfsRepositoryProvider : Provider<TfsRepository>
    {
        private const string SesTfsRepository = "SES_TFS_REPOSITORY";

        protected override TfsRepository CreateInstance(IContext context)
        {
            // Retrieve services from kernel
            HttpContextBase httpContext = context.Kernel.Get<HttpContextBase>();

            if (httpContext == null || httpContext.Session == null)
            {
                throw new Exception("No bind service found in Kernel for HttpContextBase");
            }

            return (httpContext.Session[SesTfsRepository] ?? (
                    httpContext.Session[SesTfsRepository] = new TfsRepository(context.Kernel.Get<IWorkItemStoreWrapper>()))
                ) as TfsRepository;
        }
    }
Run Code Online (Sandbox Code Playgroud)