我正在使用一种模式,其中实现接口的具体ViewModel被传递给存储库,然后该存储库填充ViewModel对象,但仅使用接口。这使得存储库稍重一些,但允许存储库在不同情况下重用。例如,具体实现可以是MVC ViewModel,或者它可以是实现接口的asp.net Page,其中每个proeprty的set访问器实际上将值放入GUI中,例如文本框。接口的实现作为映射并消除了复制的额外步骤。在广泛使用AutoMapper并且现在暴露于这种模式之后,我更喜欢这一点。通过接口/工厂填充集合?
public interface IPerson
{
int Id{set};
string Name{set};
string Address{set};
}
public class PersonRepository
{
GetPerson(int id, IPerson person)
{
//query...
person.Id = result.Id;
person.Name = result.Name;
person.Address = result.Address;
}
}
//...controller action
PersonViewModel person = new PersonViewModel();
rep.GetPerson(5, person);
虽然这里有棘手的部分。有时ViewModel需要一个项目集合,可以是索引页面,也可以是下拉菜单,或者显示一组嵌套的子对象。存储库不能实例化一个接口,所以我们提供它是一个工厂。与协方差一段时间战斗,我放弃了暴露任何类型的集合,并结束了与这两个创建并添加收藏项目的方法:
public interface IPerson
{
//...
IJobRole CreateAndAddJobRole();
}
public class PersonViewModel:IPerson
{
//collection not part of the interface
ICollection<JobRoles> JobRoles {get;set;} //= new List<JobRoles> in constructor
public CreateAndAddJobRole()
{
role = new JobRole();
JobRoles.Add(role);
return role;
}
}
public class PersonRepository
{
GetPerson(int id, IPerson person)
{
//...
foreach(var result...)
{
IJobRole role = person.CreateAndAddJobRole();
role.SomeProperty = //...
}
}
}
显然,我可能有一个处理的工作角色仓库实际上是填充集合的人。我可能实际上有更多的粒度接口,以便不同的存储库负责填充他们处理的数据。 ViewModel只会实现多个接口。也就是说,我意识到还有改进的余地,但我特意在这里,因为我没有处理收集问题的好主意。
这种设计的一个好处是没有可能被仓库滥用的集合。从来没有猜测谁是负责实例化集合本身,谁负责它,或者如果你只是一个getter,存储库可以获取集合并以无效的方式修改它。我认为这些将是罕见的事件,因为球队会知道这种模式,但总是很好,根本没有陷阱,而不是在那里有每个人都必须记住不要插手的陷阱。
事实上,感觉有点不舒服。
如何设计/展示具体类型被实例化并添加到集合中的能力,当这样做的方法只知道接口时?
是'IPerson()其中TJob:IJobRole'完全可行吗? –
Bobson
这是可能的,我想,但我很好奇你要去那里。这是否会使IPerson可以为该集合声明一个具体的类型,即'new TJob()'? (花了我几分钟)如果是这样,这很有意义,但可能会混淆ViewModel上的大量集合,因为这可能与IPerson类似。也许可以通过让其他仓库负责他们自己的类型来解决(例如IJobRole)。给我另一个想法。 –
AaronLS
非常。我会把它充实成一个完整的答案。 – Bobson