【发布时间】:2014-07-23 12:22:32
【问题描述】:
维护编辑
在使用这种方法一段时间后,我发现自己只在每个控制器中添加完全相同的样板代码,所以我决定做一些反射魔法。与此同时,我放弃了使用 MVC 来查看视图——Razor 太乏味和丑陋——所以我基本上使用我的处理程序作为 JSON 后端。我目前使用的方法是用 Route 属性装饰我的查询/命令,该属性位于一些常见的程序集中,如下所示:
[Route("items/add", RouteMethod.Post)]
public class AddItemCommand { public Guid Id { get; set; } }
[Route("items", RouteMethod.Get)]
public class GetItemsQuery : IQuery<GetItemsResponse> { }
// The response inherits from a base type that handles
// validation messages and the like
public class GetItemsResponse : ServiceResponse { }
然后我实现了一个 MVC 主机,它提取带注释的命令/查询并在启动时为我生成控制器和处理程序。有了这个,我的应用程序逻辑终于摆脱了 MVC 的麻烦。查询响应也会自动填充验证消息。我的 MVC 应用程序现在都看起来像这样:
+ MvcApp +- 全球.asax +- Global.asax.cs - 启动主机并完成 +- 网络配置在意识到我真的没有在主机之外使用 MVC 之后——并且经常遇到框架所具有的大量依赖项的问题——我实现了另一个基于 NServiceKit 的主机。在我的应用程序逻辑中无需更改任何内容,并且依赖关系降至 System.Web、NServiceKit 和 NServiceKit.Text,它们很好地处理了模型绑定。我知道这与NServiceKit/ServiceStack 的工作方式非常相似,但我现在完全脱离了正在使用的 Web 框架,所以如果出现更好的框架,我只需实现另一个主机即可。
情况
我目前正在开发一个 ASP.NET MVC 站点,该站点通过 IQueryHandler 和 ICommandHandler 抽象实现业务逻辑视图分离(使用 the almighty SimpleInjector 进行依赖注入)。
问题
我必须通过装饰器将一些自定义验证逻辑附加到QueryHandler,这本身就工作得很好。问题是,如果出现验证错误,我希望能够显示与操作将返回的视图相同的视图,但当然还有关于验证错误的信息。这是我的案例的示例:
public class HomeController : Controller
{
private readonly IQueryHandler<SomeQuery, SomeTransport> queryHandler;
public ActionResult Index()
{
try
{
var dto = this.queryHandler.Handle(new SomeQuery { /* ... */ });
// Doing something awesome with the data ...
return this.View(new HomeViewModel());
}
catch (ValidationException exception)
{
this.ModelState.AddModelErrors(exception);
return this.View(new HomeViewModel());
}
}
}
在这种情况下,我有一些由queryHandler 处理的业务逻辑,它用ValidationQueryHandlerDecorator 装饰,在适当的时候抛出ValidationExceptions。
我想要它做什么
我想要的是类似的东西:
public class HomeController : Controller
{
private readonly IQueryHandler<SomeQuery, SomeTransport> queryHandler;
public ActionResult Index()
{
var dto = this.queryHandler.Handle(new SomeQuery { /* ... */ });
// Doing something awesome with the data ...
// There is a catch-all in place for unexpected exceptions but
// for ValidationExceptions I want to do essentially the same
// view instantiation but with the model errors attached
return this.View(new HomeViewModel());
}
}
我一直在考虑一个特殊的ValidationErrorHandlerAttribute,但后来我失去了上下文,我无法真正返回正确的视图。我只是用装饰器包装IQueryHandler<,> 的方法也是如此......我看到一些奇怪的代码片段在路由上进行了一些字符串嗅探,然后通过Activator.CreateInstance 实例化一个新的控制器和视图模型 -这似乎不是一个好主意。
所以我想知道是否有一个很好的方法来做到这一点......也许我只是看不到树上的木头。谢谢!
【问题讨论】:
标签: c# asp.net-mvc decorator simple-injector