Sté*_*ane 4 asp.net-mvc design-patterns dependency-injection
我有一个搜索表单,可以在不同的提供商搜索.我开始时有一个基本控制器
public SearchController : Controller
{
    protected readonly ISearchService _searchService
    public SearchController(ISearchService searchService)
    {
        _searchService= searchService;
    }
    public ActionResult Search(...)
    {
        // Use searchService to query and return a view.
    }
}
和儿童控制器
TwitterController : SearchController
{
    ...
}
NewsController : SearchController
{
    ...
}
我使用StructureMap在控制器中插入所有依赖项.通过此设置,我可以根据正在实例化的控制器的类型更改SearchService.
x.For<ISearchService>().ConditionallyUse(o =>
      {
            o.TheDefault.Is.OfConcreteType<NewsSearchService>();
            o.If(c => c.ParentType == typeof(TwitterController))
             .ThenIt.Is.OfConcreteType<TwitterSearchService>();
             ...
      });
这甚至允许我为每个控制器设置不同的视图,(只是放置相应的文件夹(Twitter,新闻......),而父控制器仍在处理所有搜索,只需简单
return View(results) 
它显示特定于推特,新闻或其他的正确视图
现在这很酷,看起来很棒,我只有一个表单,不同的视图显示在同一页面的选项卡中.这就是这种方法开始变得复杂的地方.表单必须发布到/ Twitter以在Twitter中搜索,到/新闻搜索新闻...这意味着我应该根据我的标签更改表单的操作参数,并在表单返回时显示正确的选项卡取决于..网址?疯狂随之而来.
如果你已经建立了这样的东西或知道什么是最好的方法,欢迎提出建议.
现在我认为使用表单中的参数并发布到单个控制器会减少痛苦.我正在考虑根据此参数注入正确的SearchService.什么是最好的方法?我想过使用模型活页夹,
所以我的ActionMethod看起来像这样:
public ActionResult Search(ISearchService service, Query query)
{
    var results = service.Find(query);
}
但我认为需要在ModelBinder中进行这样的调用
ObjectFactory.GetInstance(...);
基于querystring参数来描述要使用的提供程序,这对我来说似乎并不优雅.我感到卡住,帮助:(.
每当您需要根据运行时值更改依赖关系时,Abstract Factory就是一般解决方案.
而不是将ISearchService注入到控制器中,而是注入一个ISearchServiceFactory:
public SearchController : Controller 
{ 
    private readonly ISearchServiceFactory searchServiceFactory;
    public SearchController(ISearchServiceFactory searchServiceFactory) 
    { 
        if (searchServiceFactory == null)
        {
            throw new ArgumentNullException("searchServiceFactory");
        }
        this.searchServiceFactory = searchServiceFactory; 
    } 
    public ActionResult Search(...) 
    { 
        // Use searchServiceFactory to create an ISearchService based on
        // run-time values, and use it to query and return a view. 
    } 
} 
我不清楚你需要改变哪个运行时值,但假设它是Query,ISearchServiceFactory可能定义如下:
public interface ISearchServiceFactory
{
    ISearchService Create(Query query);
}
| 归档时间: | 
 | 
| 查看次数: | 1624 次 | 
| 最近记录: |