在没有Unity.MVC的情况下解决Unity依赖关系

时间:2013-06-04 14:03:13

标签: c# unity-container dependency-resolver

我有两个使用以下Unity逻辑的项目:

container.RegisterType<IUnitOfWork, MyDbContext>(
    new HierarchicalLifetimeManager(),
    new InjectionFactory(
        c => new MyDbContext(configurationService.MySqlConnectionString)
    )
);
container.RegisterType<DbContext, MyDbContext>(
    new HierarchicalLifetimeManager()
);

第一个项目是一个使用Unity.MVC4包的Web应用程序,因此有一个定制的DependencyResolver执行一些工作 - 这完美地工作

第二个是非Web应用程序,因此使用普通的Unity软件包实例,但在使用 MyDbContext 进行调用时出错。

是个例外
  

System.Data.Entity.Core.MetadataException:指定的架构不是   有效。错误:EntityDataModel.MyProject.ssdl(2,2):错误0152:   实体框架提供程序类型   “System.Data.Entity.SqlServer.SqlProviderServices,   EntityFramework.SqlServer,Version = 6.0.0.0,Culture = neutral,   'System.Data.SqlClient'的PublicKeyToken = b77a5c561934e089'   无法加载ADO.NET提供程序。确保提供程序程序集   正在运行的应用程序可用。看到   http://go.microsoft.com/fwlink/?LinkId=260882了解更多信息。

我已经设置了两个项目来调用相同的服务,这是在一个单独的项目中,试图将问题的根源与第二个项目的Unity逻辑隔离开来。我还应该注意到我正在使用Entity Framework 6作为ORM。

我的问题是我需要Unity代码才能使第二个项目工作,或者我可以添加一些app.config条目来引用EF程序集吗?

更新 经过一些额外的工作后,我注意到如果我引用DbContext程序集:

  • EntityFramework
  • EntityFramework.SqlServer

在第二个项目中问题消失了。我想避免引用这些程序集,因为我的客户端项目不应该对ORM有任何了解。

我也尝试更新连接字符串,所以我手动指定了ORM项目的程序集(我的EDMX文件所在的位置),如StackOverflow question中所述但是没有任何区别。

  

元数据= RES://nameOfDll/Model.csdl | RES://nameOfDll/Model.ssdl | RES://nameOfDll/Model.msl

1 个答案:

答案 0 :(得分:2)

你正在以正确的方式做到这一点。

使用DI,您可以从应用程序中删除依赖项。这样您就可以获得“存储库不可知”应用程序。你已经有效地完成了它。至少在'声明'依赖项的项目上。

但是,当应用程序必须运行时,您需要指定将用于“声明的”抽象依赖项(接口,抽象类)的具体对象。

您可以通过注册将用于每个抽象依赖项的对象类型来完成此操作。在您的示例中,当IUnitOfWorkDbContext时,会提供MyDbContext的实例。

因此,“声明”依赖项的项目完全独立于特定的实现。

但是,当您注册依赖类型时,您将失去这种独立性。

让我们看一个例子:

如果我说“我口渴,我需要喝酒,但我不介意喝什么”,我依赖任何饮料,而不是特定的饮料。但如果我说“当我口渴时,我想喝可乐”我依赖可乐。

第一部分是依赖的抽象定义:“任何饮料”(如抽象IUnitOfWorkDbContext)。第二部分是具体的依赖:“可乐”(​​如MyDbContext)。

所以,只要我没有说明我想喝的东西,我就独立于可乐。但是一旦我说出来,我就会依赖。

也许您正在寻找的是一种在运行时更改存储库的方法。您可以这样做:不要在代码中注册依赖项,因为您需要使用所选的具体类型来引用项目。在外部配置(即文件)中执行此操作,以便您可以在不参考依赖项的情况下编译项目,并在运行时提供所需的程序集。

注意:当我说“声明”时,我的意思是使用任何模式来注入依赖项,例如构造函数注入(大多数建议)或任何其他注入模式(属性依赖项)。