C# MVC3中的Ninject会话范围概念
我正在使用Ninject框架构建一个MVC3应用程序。我有一个初始化很费时的服务,最终该服务将有一个包含用户特定信息的对象,然后只要用户会话处于活动状态,我就需要重新使用该服务,这样我就可以避免一次又一次地初始化该服务 所以我的问题是 当我使用Ninject绑定服务时,我应该选择什么类型的作用域,Ninject中没有每个作用域的会话,那么实现需求的最佳方法是什么?还是我走错了方向 我已经为我的一个服务创建了自定义提供程序,该提供程序将根据从当前Controller.User.Identity.Name获取的用户名详细信息创建服务。下面的代码无法工作,因为缺少userName局部变量。如何通过Ninject将用户名值传递到自定义提供程序中,以便从IContext中获取它C# MVC3中的Ninject会话范围概念,c#,asp.net-mvc,ninject,C#,Asp.net Mvc,Ninject,我正在使用Ninject框架构建一个MVC3应用程序。我有一个初始化很费时的服务,最终该服务将有一个包含用户特定信息的对象,然后只要用户会话处于活动状态,我就需要重新使用该服务,这样我就可以避免一次又一次地初始化该服务 所以我的问题是 当我使用Ninject绑定服务时,我应该选择什么类型的作用域,Ninject中没有每个作用域的会话,那么实现需求的最佳方法是什么?还是我走错了方向 我已经为我的一个服务创建了自定义提供程序,该提供程序将根据从当前Controller.User.Identity.N
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
};
}
}
}
}
公共类TfsConnectionManager提供程序:提供程序
{
受保护的覆盖TfsConnectionManager CreateInstance(IContext上下文)
{
Uri serverUri=新Uri(ConfigurationHelper.TfsServerUrl);
//连接到服务器而不进行模拟
使用(tfstreamprojectcollection baseUserConnection=tfstreamprojectcollectionfactory.GetTeamProjectCollection(serverUri))
{
//获取身份管理服务
IIdentialManagementService ims=baseUserConnection.GetService();
//获取要模拟的标识
TeamFoundationIdentity=ims.ReadIdentity
(
IdentitySearchFactor.AccountName,
用户名,//注意:如何从IContext获取用户名值???
MembershipQuery.None,
ReadIdentityOptions。无
);
//使用模拟身份进行连接
使用(TfsatmProjectCollection impersonatedConnection=new TfsatmProjectCollection(serverUri,identity.Descriptor))
{
WorkItemStore=impersonatedConnection.GetService();
返回新的TfsConnectionManager
{
商店
};
}
}
}
}
好的,您可以在应用程序中缓存/存储用户信息,并且只有在没有(最近)用户信息的情况下才能调用外部服务。在您的用户信息检索“层”,您只需编程这两种可能性
缓存在哪里,完全取决于您。例如,您可以将此信息存储在本地数据库中
显然,我理解错了,我的道歉(在我最初的回答下面)
例如,您可以使用保存静态
您的服务的成员(例如),因此它将被重用
尽管这取决于您的服务,但可能会有一些不必要的方面
效果(我曾经在Data Services和ASP.NET MVC3中这样做过一次)
应用程序我的数据上下文是有点搞砸了,因为一些魔法
发生了)。我想说的是:小心并测试它
嗯
Ninject故意不提供会话范围,因为在几乎所有情况下,让服务处于会话状态都是错误的。您应该非常小心地使用会话状态,因为它会带来很多缺点 首先尝试使用无状态应用程序
如果有充分的理由将数据置于会话范围内,则将该数据(而非服务)置于会话状态,并使用处于单例、瞬态或请求范围内的服务进行处理(数据和功能分离).我使用自定义提供程序创建实例,并在自定义提供程序中检查它是否存在于会话中 绑定如下所示
Bind<IRepository>().ToProvider(new TfsRepositoryProvider());
Bind().ToProvider(新的TfsRepositoryProvider());
自定义提供程序位于下面
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;
}
}
公共类TfsRepositoryProvider:Provider
{
private const string SesTfsRepository=“SES\u TFS\u REPOSITORY”;
受保护的覆盖TfsRepository CreateInstance(IContext上下文)
{
//从内核检索服务
HttpContextBase httpContext=context.Kernel.Get();
if(httpContext==null | | httpContext.Session==null)
{
抛出新异常(“在HttpContextBase的内核中找不到绑定服务”);
}
返回(httpContext.Session[SesTfsRepository](
httpContext.Session[SesTfsRepository]=新的TfsRepository(context.Kernel.Get())
)反义的;
}
}
抱歉,我可能无法很好地解释我的问题,服务的初始化涉及调用某些web服务,然后这些服务将返回特定于用户的信息。我不能使它成为静态的,因为它是用户特定的,所以我误解了你:)。您可以尝试在应用程序中缓存用户数据(信息),并且只有在您自己没有用户信息的情况下才调用外部服务。是的,这就是我上面真正的问题-我如何通过使用Scope的Ninject binding实现它谢谢您的反馈,我能理解你在上面提出的解决方案,这是一个非常著名的设计,但我真正想要的是如何在Ninject框架下实现它,谢谢你在这里不必对Ninject做任何事情。只需让检索用户信息的类选择是从数据库还是从服务获取信息。ASP.NET MVC 3端没有任何更改。谢谢Remo,我在原始描述中添加会话可能会让人困惑。我不是说我要使用会话来保存数据,目标是重用从会话返回的特定于用户的对象