这个问题需要一些上下文,才有意义,所以我将仅从项目描述开始。
我有一个开源项目,它是一个命令提示符样式的网站(U413.com,U413.GoogleCode.com)。该项目内置于ASP.NET MVC 3中,并使用Entity Framework4。从本质上讲,该站点允许您传递命令和参数,然后该站点返回一些数据。这个概念很简单,但是我不想使用一个巨大的IF语句来处理命令。相反,我决定做一些独特的事情,并构建一个对象,该对象包含所有可能的命令作为该对象上的方法。
该站点使用反射来定位与发送的命令相对应的方法并执行它们。此对象是根据当前用户动态构建的,因为某些用户有权访问的命令不同于其他用户(例如,管理员拥有的主持人数量多,而mod拥有的用户数量也多,等等,等等)]
我建立了一个自定义CommandModuleFactory
,它将在MVC控制器中创建,并将调用它的BuildCommandModule
方法来构建命令模块对象。我现在正在使用Ninject进行依赖项注入,并且我想逐步取消此CommandModuleFactory
,以便在不执行控制器任何工作的情况下将ICommandModule
注入到控制器中。
ICommandModule
定义了一个方法,如下所示:
public interface ICommandModule { object InvokeCommand(string command, List<string> args); }
InvokeCommand
是对自身进行反射以查找所有可能与传入命令匹配的方法的方法。
然后我有五个不同的对象,它们继承自ICommandModule
(其中一些也继承自其他模块,因此我们不重复命令):
[AdministratorCommandModule
继承自ModeratorCommandModule
,后者继承自UserCommandModule
,其继承自BaseCommandModule
。
我也有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
。这是在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
为空。我不确定在Ninject绑定阶段如何确定用户是否登录。有什么想法吗?
在执行Ninject绑定时,如何获得对登录用户的引用?还是您可以想到一种更好的方式为我的ICommandModule
进行条件绑定?
这个问题需要一些上下文,然后才有意义,因此,我仅从项目描述开始。项目背景我有一个开源项目,它是命令提示符样式...
您应该使用提供程序,而不是将逻辑放入模块中。首先,您可以创建类似于SecurityInformation类的内容,该类可以告诉您用户是否已通过身份验证以及他们的角色。目前,我认为您的实现仅使用第一个用户的授权信息来启动应用。但是,您希望每次请求此模块的实例时都检查当前用户的权限。
您的应用程序中运行的内核数量应有限(非常