繁体   English   中英

在ASP.NET MVC3模型绑定器中使用依赖注入

[英]Using Dependency Injection in ASP.NET MVC3 Model Binder

我正在使用MVC3网站,试图使用Ninject来解决我的依赖关系。 我有以下场景:

public class UserModelBinder : IModelBinder
{
    //[Inject]
    public UserDataService userData { get; set; }

    public object BindModel(
        ControllerContext controllerContext,
        ModelBindingContext bindingContext)
    {
        Guid UserID =
            (Guid)Membership.GetUser().ProviderUserKey;

        //userDataService = DependencyResolver.Current
        //    .GetService<UserDataService>();

        User user = userDataService.GetUser(UserID);

        return user;
    }
}

注意到注释的代码行?

我在Global.asax注册了绑定器

ModelBinders.Binders[typeof(User)] = new UserModelBinder();

所以我不能真正通过施工注射。

UserDataService有一系列依赖项: UserDataService -> UserRepository -> Context 所以在这里使用Ninject会很好。

问题是,当我取消注释[Inject]上面的userData声明,并尝试让Ninject注入对象作为参数时,由于某种原因它不起作用:我得到空引用异常。

可能是UserDataService没有接口,我将对象绑定到自身: kernel.Bind<UserDataService>().ToSelf(); ??

我在代码中有另一个注释行:

userDataService = DependencyResolver.Current
    .GetService<UserDataService>();

如果取消注释,设置工作,我会插入正确的对象,但现在我们依赖于DependencyResolver,这并不比说userDataService = new UserDataService()好多少

我错过了什么吗? 是否有另一种方法将对象作为参数注入,而不是引入对Ninject或DependencyResolver的依赖?

模型绑定器应该只进行数据转换,不应该依赖于任何服务,当然也不会触发任何数据库通信。 这应该在您的应用程序的另一部分中完成。 你的Action方法应该只需要一个Guid userId ,你应该调用userDataService.GetUser(UserID); 来自您的控制器(或在较低层,例如,在业务命令内 )。 通过这样做,您的问题将不存在。

你可以这样做:

public class UserModelBinder : IModelBinder
{
    public Func<UserDataService> UserData { get; set; }

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        Guid UserID = (Guid)Membership.GetUser().ProviderUserKey;

        User u = UserData().GetUser(UserID);

        return u;
    }
}

然后当你连线时:

ModelBinders.Binders[typeof(User)] = new UserModelBinder() 
{  
    userData = () => DependencyResolver.Current.GetService<UserDataService>();
}

好处是您的UserModelBinder不知道正在使用容器,同时仍然可以打开注入。

但我同意史蒂文的意见 - 使用模型绑定器似乎并不合适。 相反,您可以将ICurrentUserContext注入控制器,其中实现返回当前用户。 然后,您甚至不需要向控制器操作添加参数。

使用DependencyResolver.Current来获取服务。 这实际上比使用new 好得多,因为这意味着您没有将该服务与服务类型相结合。 您可以稍后决定将UserDataService作为抽象并插入不同的变体而不更改您的客户端代码,这真的是重点。

此外, DependencyResolver.Current是一个可设置的IDependencyResolver ,因此您可以自己实现该接口,如果您喜欢该框架,则使用Ninject支持它的类。

在MVC3中进行依赖注入的另一种方法是设置自己的IControllerActivator ,如果你愿意,它允许你进行构造函数注入。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM