在MVC 3中,我一直在重构我的控制器,通过使用我成功完成的泛型删除一些重复的代码,但现在我正在尝试重构我的观点,但我似乎无法调整模型该视图用于使用泛型。
以下是我重构的抽象基本控制器的相关部分:
public abstract class CrudController<TEntity> : Controller where TEntity : Entity, INamedEntity, IOrderedEntity, IHasMembers, new()
{
private readonly IUnitOfWork _unitOfWork;
protected readonly IRepository<TEntity> Repository;
protected CrudController(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
Repository = _unitOfWork.RepositoryFor<TEntity>();
}
public ActionResult Edit(int id)
{
return PartialView(Repository.FindById(id));
}
// More actions here...
}
以下是我的实际控制器(自重构以来它们非常基本):
public class StatusController : CrudController<MemberStatus>
{
public StatusController(IUnitOfWork unitOfWork) : base(unitOfWork)
{
}
}
public class PositionController : CrudController<MemberPosition>
{
public PositionController(IUnitOfWork unitOfWork) : base(unitOfWork)
{
}
}
请注意 MemberStatus 和 MemberPosition 都实现'Entity,INamedEntity,IOrderedEntity,IHasMembers'
现在,这是我要重构的两个控制器的编辑视图:
@model MyApp.Domain.Entities.MemberStatus
@using (Html.BeginForm("Save", @ViewContext.RouteData.Values["Controller"].ToString(), FormMethod.Post, new { id = "EntityForm" }))
{
@Html.Hidden("Id")
<label class="Name">
<span>New Name:</span><br />
@Html.EditorFor(x => x.Name)
</label>
}
@model MyApp.Domain.Entities.MemberPositions
@using (Html.BeginForm("Save", @ViewContext.RouteData.Values["Controller"].ToString(), FormMethod.Post, new { id = "EntityForm" }))
{
@Html.Hidden("Id")
<label class="Name">
<span>New Name:</span><br />
@Html.EditorFor(x => x.Name)
</label>
}
您可以看到视图几乎相同,但声明模型的第一行除外。我想知道如何传递一个通用参数,就像我对控制器所做的那样,我认为(在我的天真中)看起来像下面这样,但这显然不起作用。
@model <TEntity> where TEntity : Entity, INamedEntity, IOrderedEntity, IHasMembers, new()
如何重构这两个视图(通过在Shared文件夹中放置一个通用视图)来实现视图中的非具体模型?任何建议都表示赞赏。
仅供参考 - 我认为(虽然我没有尝试过)我可以使用ViewModel,但在这种情况下我不想这样做(因为我必须实现从每个实体的实体映射到ViewModel,这有点抵消了这个重构的目的。)
答案 0 :(得分:3)
如果两个模型都具有公共属性,请在界面中创建具有这些属性的接口,然后使两个模型都实现该接口。现在创建一个强类型的视图到该接口。另一个选项只是一个在运行时动态评估的弱类型视图。
答案 1 :(得分:2)
您是否可以将模型定义为您使用的接口而不是实现许多接口的对象?:
@model INamedEntity
@using (Html.BeginForm("Save", @ViewContext.RouteData.Values["Controller"].ToString(), FormMethod.Post, new { id = "EntityForm" }))
{
@Html.EditorForModel()
}
为此,您可以为INamedEntity界面创建一个编辑器模板。
答案 2 :(得分:1)
@model Entity
@if (Model is INamedEntity)
{
@{ Html.RenderPartial("NamedEntityFields", (INamedEntity)Model); }
}
@if (Model is IOrderedEntity)
{
@{ Html.RenderPartial("OrderedEntityFields", (IOrderedEntity)Model); }
}
NamedEntityFields.cshtml:
@model INamedEntity
@* put name specific fields here *@