在MVC3 Ninject会话范围的概念 [英] Ninject session scope concept in MVC3

查看:77
本文介绍了在MVC3 Ninject会话范围的概念的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建立使用Ninject框架MVC3应用程序。我有一个服务,是费时进行初始化,并在年底这项服务将有一个包含用户特定信息的对象,然后我需要在用户会话活动,只要重新使用该服务,使我可避免一次又一次地初始化服务

所以我的问题是

当我使用绑定我应该选择Ninject什么样的范围内的服务中,每个范围中没有会议Ninject,那么什么是实现这个需求的最佳方式是什么?还是我去了一个错误的方向呢?

我已经为我的服务,这将创建基于从当前Controller.User.Identity.Name抓住用户名细节服务的一个自定义提供。下面的code将无法工作,因为用户名本地变量缺失,我怎么能传递用户名值到通过Ninject我的自定义提供,让我可以从IContext ??

把它捡起来

 公共类TfsConnectionManagerProvider:提供< TfsConnectionManager>
    {
        保护覆盖TfsConnectionManager的CreateInstance(IContext上下文)
        {
            乌里serverUri =新的URI(ConfigurationHelper.TfsServerUrl);
            //连接到服务器,而无需模拟
            使用(TfsTeamProjectCollection baseUserConnection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(serverUri))
            {
                //获取身份管理服务
                IIdentityManagementService IMS = baseUserConnection.GetService< IIdentityManagementService>();                //获取身份冒充
                TeamFoundationIdentity身份= ims.ReadIdentity
                (
                    IdentitySearchFactor.AccountName,
                    用户名,//注:我怎样才能从IContext用户名值?
                    MembershipQuery.None,
                    ReadIdentityOptions.None
                );                //连接时使用模拟的标识
                使用(TfsTeamProjectCollection impersonatedConnection =新TfsTeamProjectCollection(serverUri,identity.Descriptor))
                {
                    WorkItemStore店= impersonatedConnection.GetService< WorkItemStore>();                    返回新TfsConnectionManager
                    {
                        商店=店
                    };
                }
            }
        }
    }


解决方案

我变成使用自定义提供用于创建实例,并在自定义提供我检查它是否在会话存在与否。

绑定是如下完成

 绑定< IRepository>()ToProvider(新TfsRepositoryProvider());

自定义提供低于

 公共类TfsRepositoryProvider:提供< TfsRepository>
    {
        私人常量字符串SesTfsRepository =SES_TFS_REPOSITORY;        保护覆盖TfsRepository的CreateInstance(IContext上下文)
        {
            //从内核服务
            HttpContextBase的HttpContext = context.Kernel.Get< HttpContextBase>();            如果(HttpContext的== NULL || httpContext.Session == NULL)
            {
                抛出新的异常(在内核中发现了HttpContextBase没有绑定服务);
            }            返回(httpContext.Session [SesTfsRepository]?(
                    httpContext.Session [SesTfsRepository] ​​=新TfsRepository(context.Kernel.Get< IWorkItemStoreWrapper>()))
                )作为TfsRepository;
        }
    }

I am building a MVC3 app using Ninject framework. I have a service that is time-consuming to initialize, and at the end this service will has an object that contains user-specific information, then I need to re-use that service as long as the user session is active, so that I can avoid to initialize that service again and again

So my question is

When I bind the service using Ninject what kind of scope should I pick, there is no session per scope in Ninject, so what is the best way to implement the requirement? or did I went to a wrong direction at all?

I've created a custom provider for one of my services that will create the service based on username details that is grabbed from current Controller.User.Identity.Name. The code below won't work because the userName local variable is missing, how can I pass the user name value into my custom provider via Ninject, so that I can pick it up from 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
                    };
                }
            }
        }
    }

解决方案

I turn out to use custom Provider for creating the instance and in the custom provider I checked if it exists in session or not.

The binding is done as following

Bind<IRepository>().ToProvider(new TfsRepositoryProvider());

The custom Provider is below

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

这篇关于在MVC3 Ninject会话范围的概念的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆