Che*_*hev 12 c# asp.net-mvc dependency-injection ninject asp.net-mvc-3
这个问题在它有意义之前需要一些上下文,所以我将从项目的描述开始.
我有一个开源项目,这是一个命令提示式网站(U413.com,U413.GoogleCode.com).该项目是在ASP.NET MVC 3中构建的,并使用Entity Framework 4.本质上,该站点允许您传入命令和参数,然后站点返回一些数据.这个概念相当简单,但我不想使用一个巨大的IF语句来处理命令.相反,我决定做一些有点独特的事情,并构建一个包含所有可能命令作为对象方法的对象.
该站点使用反射来定位与已发送命令对应的方法并执行它们.此对象是基于当前用户动态构建的,因为某些用户可以访问不同于其他用户的命令(例如,管理员拥有的不仅仅是主持人,而且mod还有多个用户等等).
我构建了一个CommandModuleFactory将在MVC控制器中创建的自定义,并将调用它的BuildCommandModule方法来构建命令模块对象.我现在正在使用Ninject进行依赖注入,我想逐步淘汰这个CommandModuleFactory,支持ICommandModule在没有控制器做任何工作的情况下注入控制器.
ICommandModule 有一个方法定义,如下所示:
public interface ICommandModule
{
object InvokeCommand(string command, List<string> args);
}
Run Code Online (Sandbox Code Playgroud)
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>();
}
}
Run Code Online (Sandbox Code Playgroud)
这里发生了一些事情.首先,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;
}
Run Code Online (Sandbox Code Playgroud)
IUserRepository在加载Ninject模块以构建我的命令模块之前,您可以看到我映射到其具体类型(尽量不要将Ninject绑定模块与我的命令模块混淆:S).然后我用它kernel.Get<IUserRepository>()来解决我的Ninject模块对它的依赖.
我的问题HttpContext.Current.User是null.我不知道如何判断用户是否在Ninject绑定阶段登录.有任何想法吗?
当我在进行Ninject绑定时,如何获取对登录用户的引用?或者你能想到一个更好的方法让我为我做条件绑定ICommandModule吗?
任何帮助表示赞赏!
Vad*_*dim 12
您应该使用提供程序而不是将逻辑放在模块中.首先,您可以创建类似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>();
}
}
Run Code Online (Sandbox Code Playgroud)
然后将指定绑定
Kernel.Bind<ICommandModule>().ToProvider<CommandModuleProvider>();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1506 次 |
| 最近记录: |