c# – 如何根据用户替换Ninject绑定?
这个问题需要一些上下文才能有意义,所以我将从项目的描述开始.
项目背景 我有一个开源项目,它是一个命令提示样式的网站(U413.com,U413.GoogleCode.com).该项目构建在ASP.NET MVC 3中,并使用实体框架4.本质上该站点允许您传递命令和参数,然后站点返回一些数据.这个概念很简单,但是我不想使用一个巨大的IF语句来处理命令.相反,我决定做一些有点独特的事情,并构建一个包含所有可能的命令作为对象上的方法的对象. 该站点使用反射来定位与发送的命令相对应的方法并执行它们.该对象是基于当前用户动态构建的,因为某些用户可以访问与其他用户不同的命令(例如,管理员拥有多个主持人,而且拥有超过用户等等). 我创建了一个自定义的CommandModuleFactory,它将在MVC控制器中创建,并将其称为BuildCommandModule方法来构建一个命令模块对象.我现在正在使用Ninject进行依赖注入,我想逐步删除此CommandModuleFactory,有利于将ICommandModule注入到控制器中,而无需控制器执行任何工作. ICommandModule有一个方法定义,像这样: public interface ICommandModule { object InvokeCommand(string command,List<string> args); } InvokeCommand是执行自身反射以查找可能匹配传入命令的所有方法的方法. 然后我有五个不同的对象从ICommandModule继承(其中一些继承自其他模块,所以我们不重复命令): AdministratorCommandModule继承自继承自BaseCommandModule的UserCommandModule的ModeratorCommandModule. 然后我还有VisitorCommandModule继承自BaseCommandModule,因为访问者将无法访问其他三个命令模块中的任何命令. 希望你可以开始看看它是如何工作的.我为自己的工作感到非常自豪. 问题 我想让Ninject为我构建我的命令模块,并绑定到ICommandModule,以便我可以让我的MVC控制器依赖于ICommandModule,它会收到正确的版本.这是我的Ninject模块看起来像绑定发生的位置. public class BuildCommandModule : NinjectModule { private bool _isAuthenticated; private User _currentUser; public BuildCommandModule( bool isAuthenticated,string username,IUserRepository userRepository ) { this._isAuthenticated = isAuthenticated; this._currentUser = userRepository.GetUserBy_Username(username); } public override void Load() { if (_isAuthenticated) if (_currentUser.Administrator) //load administrator command module this.Bind<ICommandModule>().To<AdministratorCommandModule>(); else if (_currentUser.Moderator) //Load moderator command module this.Bind<ICommandModule>().To<ModeratorCommandModule>(); else //Load user command module this.Bind<ICommandModule>().To<UserCommandModule>(); else //Load visitor command module this.Bind<ICommandModule>().To<VisitorCommandModule>(); } } 这里有几件事情发生.首先,Ninject模块取决于几件事情.它取决于一个布尔值,指示用户是否被认证(以确定它是否是其中一个登录命令模块或访问者命令模块).接下来它取决于字符串用户名和IUserRepository.这里是我的Mappings在Global.asax中定义的地方. protected override IKernel CreateKernel() { var kernel = new StandardKernel(); kernel.Bind<IBoardRepository>().To<BoardRepository>(); kernel.Bind<IReplyRepository>().To<ReplyRepository>(); kernel.Bind<ITopicRepository>().To<TopicRepository>(); kernel.Bind<IUserRepository>().To<UserRepository>(); kernel.Load(new BuildCommandModule(User.Identity.IsAuthenticated,User.Identity.Name,kernel.Get<IUserRepository>())); return kernel; } 在我加载Ninject模块以构建我的命令模块之前,我可以看到我将IUserRepository映射到其具体类型(尽量不要将Ninject绑定模块与我的命令模块混淆:S).然后我使用kernel.Get< IUserRepository>()来解决我的Ninject模块对它的依赖. 我的问题是HttpContext.Current.User为null.我不知道如何判断用户是否在Ninject绑定阶段登录.有任何想法吗? 当我进行Ninject绑定时,如何获得登录用户的引用?或者你能想到一个更好的方法来为我的ICommandModule做条件绑定吗? 任何帮助是赞赏! 解决方法
您应该使用提供者,而不是将逻辑放在模块中.首先,您可以创建一个类似SecurityInformation类,可以告诉您用户是否被认证和他们的角色.目前您的实现我认为只使用第一个用户的授权信息来启动应用程序.但是,每次请求此模块的实例时,都希望检查当前用户的权限.
public class CommandModuleProvider : IProvider { public Type Type { get { return typeof(ICommandModule); } } public object Create(IContext context) { var securityInfo = context.Kernel.Get<SecurityInformation>(); if (securityInfo.IsAuthenticated) if (securityInfo.IsCurrentUserAdministrator) //load administrator command module return context.Kernel.Get<AdministratorCommandModule>(); else if (securityInfo.IsCurrentUserModerator) //Load moderator command module return context.Kernel.Get<ModeratorCommandModule>(); else //Load user command module return context.Kernel.Get<UserCommandModule>(); else //Load visitor command module return context.Kernel.Get<VisitorCommandModule>(); } } 然后绑定将被指定为 Kernel.Bind<ICommandModule>().ToProvider<CommandModuleProvider>(); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |