我通过继承RouteBase创建自定义路由。我有一个依赖,我想与IoC连接。方法GetRouteData只需要HttpContext,但我想在我的工作单元中添加....不知何故。
我正在使用StructureMap,但有关如何使用任何IoC框架执行此操作的信息会有所帮助。
答案 0 :(得分:4)
嗯,这是我们的解决方案。许多小细节可能会被省略,但总的想法就在这里。这个答案可能是原始问题的一种脱离,但它描述了问题的一般解决方案。
我将尝试解释负责用户在运行时创建的纯自定义HTML页面的部分,因此无法拥有自己的Controller / Action。因此路由应该以某种方式在运行时构建,或者使用自定义IRouteConstraint进行“全部捕获”。
首先,让我们说明一些事实和要求。
所以我们这样做:
是的,负责我们所有内容页面的特殊控制器。并且唯一的操作是Display(int id)
(实际上我们有一个特殊的ViewModel作为参数,但为了简单起见我使用了int id
。
包含其所有数据的页面由Display()
方法中的ID解析。如果找不到页面,该方法本身会返回ViewResult
(在PageViewModel
后强列入)或NotFoundResult
。
我们必须在某处定义实际请求的URL用户是否引用了我们的一个自定义页面。为此,我们有一个特殊的IsPageConstraint
来实现IRouteConstraint
接口。在我们约束的Match()
方法中,我们只需调用PageRepository
来检查是否有与我们请求的网址匹配的网页。我们通过StructureMap注入了PageRepository。如果我们找到该页面,那么我们将“id”参数(带有值)添加到RouteData字典,并由PageController.Display(int id)
自动绑定到DefaultModelBinder
。
但我们需要一个RouteData参数来检查。我们在哪里?来了...
重要说明:此路由在路由映射列表的最后定义,因为它非常通用,而不是特定的。我们首先检查所有明确定义的路由,然后检查Page
(如果需要,可以轻松更改)。
我们只是简单地映射我们的路线:
routes.MapRoute("ContentPages",
"{*pagePath}",
new { controller = "Page", action = "Display" }
new { pagePath = new DependencyRouteConstraint<IsPageConstraint>() });
停止!映射中出现DependencyRouteConstraint
的内容是什么?好吧,那就是诀窍。
这只是IRouteConstraint
的另一个通用实现,只需要“real” IRouteConstraint
(IsPageConstraint)并解析它(给定的TConstraint
)调用Match()
方法。它使用依赖注入,因此我们的IsPageConstraint
实例注入了所有实际依赖项!
我们的DependencyRouteConstraint
只需调用dependentConstraint.Match()
提供所有参数,因此只需将实际的“匹配”委托给“真正的”IRouteConstraint。
注意:此类实际上依赖于ServiceLocator。
我们有这样的方式:
Route
清晰干净; DependencyRouteConstraint
; IRouteConstraint
都会在需要时使用依赖注入; 希望这有帮助。
答案 1 :(得分:1)
所以,问题是:
这就是为什么我没有看到RouteBase类的子代是一些DB工作依赖的好地方。它使一切紧密耦合,不可扩展。实际上不可能执行依赖注入。
从现在起(我猜有一些已经在运行的系统)你实际上只有一个或多或少可行的选项:
Route
中获得对静态服务定位器本身的依赖。使用CSL,您只需在GetRouteData
内打电话:
var uow = ServiceLocator.Current.GetService<IUnitOfWork>();
或只使用StructureMap(没有CSL外观):
var uow = ObjectFactory.GetInstance<IUnitOfWork>();
你已经完成了。又脏又脏。关键字实际上是“脏”的:)
当然,有更灵活的解决方案,但需要进行一些架构更改。如果您提供有关您在路线中获得的确切数据的更多详细信息,我可以尝试解释我们如何解决Pages
路由问题(使用DI和自定义IRouteConstraint
)。