微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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>();

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐