如何从ASP.NET MVC Web项目中正确地分离Structure Map依赖项解析器?

时间:2011-02-08 21:34:27

标签: asp.net-mvc dependency-injection asp.net-mvc-3 structuremap loose-coupling

在使用ASP.NET MVC开发Web项目时,我遇到了耦合问题。 当我构建自定义控制器工厂(或依赖解析器,如果使用MVC 3),我需要这个工厂知道从哪里获取依赖关系。这是我的代码:

//from Global.asax.cs

DependencyResolver.SetResolver(new StructureMapControllerFactory());
class StructureMapControllerFactory: IDependencyResolver {
    Container repositories;

    public StructureMapControllerFactory()
    {
        repositories = new RepositoriesContainer();
    }
    //... rest of the implementation
}
class RepositoriesContainer: Container
{
   public RepositoriesContainer()
   {
      For<IAccountRepository>().Use<SqlAccountRepository>();
      //...
   }
}

StructureMapControllerFactory类负责将依赖项注入控制器。正如我所说,它需要知道在哪里找到这些依赖项(我的意思是具体的类,如服务和存储库实现)。

我有一个名为MySite.Data的独立类库,其中包含所有实现细节。合同(例如IAccountRepository)存在于库MySite.Contracts中。现在,如果我直接从MVC项目引用这个MySite.Data库,我的站点和它的数据检索实现之间将存在依赖关系。问题是如何删除它?在这种情况下,最佳做法是什么?

我确定它确实有很多变通办法,只是我还没找到。

1 个答案:

答案 0 :(得分:3)

嗯,正如我所看到的那样,你无法做到这一点。您的MVC项目确实需要了解它将要使用的具体类。

无论如何,您必须在某处提供这些容器注册,并且您将获得定义该类型的项目/程序集的依赖性。不久,您必须从MVC项目中引用MySite.Data。像那样:

  • MySite.Data对MVC项目一无所知
  • MVC项目知道具体的存储库类型,以提供正确的容器注册。

您可以使用StructureMap Registry对象简化生活,但您还需要在某处包含这些注册表。通常这些是在主项目或一些“StructureMap-adapter”项目中,但无论如何你都需要参考。

我建议你:

  • 使用MVC3并删除自定义IControllerFactory,如果您只将其用于Controllers的DI。
  • 使用StructureMap Registry对象提供所需的每个IoC注册。
  • 使用StructureMap程序集扫描功能提供组件发现。
  • 使用更为常见的DependencyResolver内容,即不是StructureMapControllerFactory而是CommonServiceLocator代替StructureMap adapter
  • 尝试从主应用程序中的StructureMap本身进行抽象。

当然,不要害怕在主项目中引用 - 它们没有任何关于耦合的东西。它不会降低可维护性。但错误的架构确实如此,所以要担心,而不是简单的参考。