【发布时间】:2011-04-23 14:57:36
【问题描述】:
我将从这里开始介绍一些背景知识。我们有一个 ASP.Net MVC Web 应用程序,它位于一个大致基于Onion Architecture 概念的结构上。因此,我们有以下(简化的)垂直结构:
- ASP.Net MVC 控制器层
- 应用服务层
- 业务服务层
注意:以上内容已简化,因为它不处理与此问题无关的视图、存储库、域对象等。
对于水平结构,我们有一些由我们称为“项目类型”定义的主要区域(为简单起见,本题将处理两个示例项目类型:“ItemTypeA”、“ItemTypeB”等)。
我们有一个业务服务接口,每个项目类型都有一个单独的实现:
public interface ISampleBusinessService
{
string SampleMethod(string arg);
}
public class ItemTypeASampleBusinessService : ISampleBusinessService
{
public string SampleMethod(string arg)
{
return "Item Type A: " + arg;
}
}
public class ItemTypeBSampleBusinessService : ISampleBusinessService
{
public string SampleMethod(string arg)
{
return "Item Type B: " + arg;
}
}
上面是一个使用业务服务的应用服务:
public interface ISampleAppService
{
string SampleMethod(string arg);
}
public class SampleAppService
{
private readonly ISampleBusinessService service;
public SampleAppService(ISampleBusinessService service)
{
this.service = service
}
public string SampleMethod(string arg)
{
return service.SampleMethod(arg);
}
}
上面是我们使用应用服务的控制器:
public class SampleController : Controller
{
private ISampelAppService service
public SampleController(ISampleAppService service)
{
this.service = service;
}
public PartialViewResult SampleAction(string arg)
{
return PartialView( service.SampleMethod(arg) );
}
}
请注意,控制器、应用程序服务接口和实现以及业务服务接口都是通用的——它们不关心正在使用的项目类型。但是,业务服务实现特定于项目类型。当我们调用控制器上的 action 方法(通过视图中的 RenderAction)时,我们知道我们正在处理的项目类型,但我们不确定确定使用哪个业务服务实现的最佳方法是什么。我们考虑了几个选项:
- 基类控制器并创建特定于项目类型的控制器继承者,然后与应用服务类似。这感觉像是一个弱解决方案 - 我们最终会编写一些在功能方面没有添加任何内容的类,除了确定我们正在处理的项目类型。
- 将标志向下传递到服务层并在工厂中创建服务实现(即,在其 CreateInstance 方法中采用“itemType”参数的 SampleBusinessServiceFactory)。这样做的问题是我们将一个变量向下传递了几个层,以便我们可以决定一个实现。到目前为止,我们一直在使用这种方法。
- 泛型 - 我们还没有真正考虑过这一点,但似乎也存在一些困难(如何从视图中的 ActionResult 调用中调用具有泛型的 Action 方法?)。从某种意义上讲,它类似于向下传递标志,但将基于强类型对象/服务,而不是使用枚举/魔术字符串。
哪种方法最适合解决这个问题?欢迎新的选择。
我们将不胜感激提供的任何帮助。
干杯,
扎克
【问题讨论】:
标签: asp.net-mvc design-patterns architecture domain-driven-design