您如何根据用户替换Ninject绑定?

问题描述 投票:12回答:2

这个问题需要一些上下文,才有意义,所以我将仅从项目描述开始。

项目背景

我有一个开源项目,它是一个命令提示符样式的网站(U413.comU413.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进行条件绑定?

这个问题需要一些上下文,然后才有意义,因此,我仅从项目描述开始。项目背景我有一个开源项目,它是命令提示符样式...

c# asp.net-mvc asp.net-mvc-3 dependency-injection ninject
2个回答
12
投票

您应该使用提供程序,而不是将逻辑放入模块中。首先,您可以创建类似于SecurityInformation类的内容,该类可以告诉您用户是否已通过身份验证以及他们的角色。目前,我认为您的实现仅使用第一个用户的授权信息来启动应用。但是,您希望每次请求此模块的实例时都检查当前用户的权限。


3
投票

您的应用程序中运行的内核数量应有限(非常

© www.soinside.com 2019 - 2024. All rights reserved.