在MVC模型和视图之间使用接口

问题描述:

我正在使用asp.net MVC 2开发一个站点。 IUser被用作模型和视图之间的接口,以更好地分离关注点。然而,这里变得有点混乱。在处理用户登录的控制器中:我有以下内容:在MVC模型和视图之间使用接口

 IUserBll userBll = new UserBll(); 
     IUser newUser = new User(); 

     newUser.Username = answers[0].ToString(); 
     newUser.Email = answers[1].ToString(); 

     userBll.AddUser(newUser); 

User class在Web项目中定义为实现IUser的具体类。 DAL中有一个类似的类实现相同的接口并用于保存数据。但是,调用userBll.AddUser时,即使两个Users类都实现接口(InvalidCastException),也不能将User类型的newUser转换为DAL User类。

使用转换运算符可能是一个选项,但它会使DAL和web之间的依赖关系与使用接口的初始目标相悖。

有什么建议吗?

你应该有一个处理依赖注入的项目。 此项目引用您的域项目(其中IUserBll已定义)以及具有DLL实现的项目。所以你的MVC项目将引用依赖项注入项目并给定一个特定的接口,请求DI实现它。

看看StructureMap或温莎城堡。

//Global.asax 
    protected void Application_Start() 
    { 
     ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory()); 
    } 

    //Dependency Injection Project: 
    public class StructureMapControllerFactory : DefaultControllerFactory 
    { 
     protected override IController GetControllerInstance(Type controllerType) 
     { 
      if (controllerType != null) 
      { 
       return (IController)ObjectFactory.GetInstance(controllerType); 
      } 
      return null; 
    } 
} 

这样,你的控制器看起来更像:

public class SomeController 
{ 
    private IUserBll _repository; 
    public SomeController(IUserBll repository) 
    { 
    _repository = repository; 
    } 

    [AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult Index(Someform f) 
    { 
     ... 
     _repository.AddUser(...); 
    } 
} 

当您使用例如StructureMap控制器厂,MVC将得到的依赖复制到幕后控制器。

+0

是的,我明白DI的好处。然而,这里的主要问题是处理用户类型。 _repository.AddUser(...)仍然传递一个User对象,对吧? – Icerman 2010-05-21 04:28:53

+0

我的观点是通过在(DI项目和Web)和(项目使用IUserBll和Web)之间建立依赖关系,可以解决“DAL和web之间的依赖关系,这违背了使用接口的初始目标”。 Web项目永远不会引用/具有对DAL项目的依赖关系。控制器工厂将使DAL.UserBll的存储库实例化并将其作为IUserBll返回。 – CRice 2010-05-21 06:39:42

+0

同意。我的另一个难题是IUser及其在DAL和Web中的实现。 IUser定义了常用属性,DAL和Web可能有不同的实现,其中只有DAL或Web关心的附加属性。但它在我看来,而不是将Web用户转换为DAL用户,我需要使用IUser属性填充DAL用户,而不是在IUserBll.AddUser(IUser)中分配DAL用户特定的合适的属性。 – Icerman 2010-05-21 17:41:21