我目前的应用程序允许用户通过一组管理屏幕定义自定义网页表单。它本质上是一个EAV类型的应用程序。因此,我不能硬编码HTML或ASP.NET标记来呈现给定的页面。相反,UI从服务层请求一个Form对象的实例,然后使用多个RDMBS表构造一个实例。表格中包含有一种类,你会期望在这样的背景下看:Form
=>IEnumerable<FormSections>
=>IEnumerable<FormFields>
这是IOC的典型用例吗?
这里的服务层的样子:
public class MyFormService: IFormService{
public Form OpenForm(int formId){
//construct and return a concrete implementation of Form
}
}
一切工作出色(一会儿) 。用户界面对于给定表单中存在哪些部分/字段不太明智:它将其接收的Form对象愉快地呈现为功能性ASP.NET页面。
几周后,我从业务中获得了一项新要求:查看表单的不可编辑(即只读)版本时,某些字段值应该合并在一起,其他设计/计算字段应该是添加。我说没问题。简单修改我的服务等级,使其方法更加明确:
public class MyFormService: IFormService{
public Form OpenFormForEditing(int formId){
//construct and return a concrete implementation of Form
}
public Form OpenFormForViewing(int formId){
//construct and a concrete implementation of Form
//apply additional transformations to the form
}
}
再次,一切都很好,平衡已恢复到部队。用户界面对于表单中的内容仍然是不可知论的,我们关注的分离已经实现。然而,短短几周后,企业提出了一项新的要求:在某些情况下,我们应该只应用的一些上面引用的形式转换。除非我想结束一些方法的爆炸(OpenFormViewingScenario1,OpenFormViewingScenario2等),否则感觉就像“显式方法”已经到了死胡同的地步。相反,我介绍的间接另一个层面:
public interface IFormViewCreator{
void CreateView(Form form);
}
public class MyFormService: IFormService{
public Form OpenFormForEditing(int formId){
//construct and return a concrete implementation of Form
}
public Form OpenFormForViewing(int formId, IFormViewCreator formViewCreator){
//construct a concrete implementation of Form
//apply transformations to the dynamic field list
return formViewCreator.CreateView(form);
}
}
从表面上看,这似乎是可以接受的方法,但也有一定的气味。也就是说,UI一直处于对OpenFormForViewing的实现细节的无知幸福中,必须具备并创建一个IFormViewCreator的实例。
- 我的问题是双重的:有没有 更好的方式来实现 可组合我之后? (可能通过 使用IoC容器或家庭 滚动工厂创建 具体的IFormViewCreator)?
- 我在这里根本搞砸了 抽象吗?
+1也可以做到这一点。 – Lucero 2010-01-27 23:43:57
我同意你的气味。看起来像UI不应该知道IFormViewCreator。对你来说一个问题:用户界面是否了解你应该返回的那些“味道”的参数?对于UI来说,传递一个对象作为确定应用哪个转换的各种值的容器可能更有意义。然后,您的OpenFormForViewing()方法将负责转发到工厂类,或明确指出要返回哪些“风味”。 – 2010-02-08 15:03:55