簡體   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