在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将得到的依赖复制到幕后控制器。
是的,我明白DI的好处。然而,这里的主要问题是处理用户类型。 _repository.AddUser(...)仍然传递一个User对象,对吧? – Icerman 2010-05-21 04:28:53
我的观点是通过在(DI项目和Web)和(项目使用IUserBll和Web)之间建立依赖关系,可以解决“DAL和web之间的依赖关系,这违背了使用接口的初始目标”。 Web项目永远不会引用/具有对DAL项目的依赖关系。控制器工厂将使DAL.UserBll的存储库实例化并将其作为IUserBll返回。 – CRice 2010-05-21 06:39:42
同意。我的另一个难题是IUser及其在DAL和Web中的实现。 IUser定义了常用属性,DAL和Web可能有不同的实现,其中只有DAL或Web关心的附加属性。但它在我看来,而不是将Web用户转换为DAL用户,我需要使用IUser属性填充DAL用户,而不是在IUserBll.AddUser(IUser)中分配DAL用户特定的合适的属性。 – Icerman 2010-05-21 17:41:21