Entity Framework 使用 Unity 时出错
Entity Framework Error when using Unity
在尝试解析我的服务 class 时,我收到一个错误,提示无法构建 DbContext
,因为它是一个抽象 class。错误信息在这里:
Unity.Exceptions.ResolutionFailedException: 'Resolution of the dependency failed, type = 'MyService.MyClass', name = '(none)'.
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, System.Data.Common.DbConnection, is an abstract class and cannot be constructed. Are you missing a type mapping?
-----------------------------------------------
At the time of the exception, the container was:
Resolving ...
...
Resolving MyApp.MyRepository,(none)
Resolving parameter 'myDbContext' of constructor MyApp.MRepository(MyApp.IMyDbContext myDbContext)
...
Resolving parameter 'existingConnection' of constructor MyApp.MyDbContext(System.Data.Common.DbConnection existingConnection, System.Data.Entity.Infrastructure.DbCompiledModel model, System.Boolean contextOwnsConnection)
Resolving System.Data.Common.DbConnection,(none)
'
DBContext 如下所示:
public class MyDbContext : System.Data.Entity.DbContext, IMyDbContext
{
public MyDbContext()
: base("MainConnectionString")
{
}
我的猜测是 EF 在配置文件中查找连接字符串;但连接字符串已定义:
<connectionStrings>
<add name="MainConnectionString" connectionString="Server=.\SQLEXPRESS;Database=MyDB;User Id= . . ." providerName="System.Data.SqlClient" />
</connectionStrings>
统一注册:
因此,我的问题是 EF 如何计算出如何构建这个 class,显然我在配置中遗漏了一些东西。
UnityContainer container = new UnityContainer();
container.RegisterType<IMyDbContext, MyDbContext>();
container.RegisterType<IMyRepository, MyRepository>();
container.RegisterInstance<IUnityContainer>(container);
根据this answer:
Unity will resolve a concrete type (.Resolve), but interfaces have to be explicitly registered by associating them with concrete types.
那么,你有两个选择:
- 向Unity注册
IMyDbContext
接口
- 停止使用
IMyDbContext
并使用具体类型(在这种情况下 Unity 将自动解析它,尽管您可能需要手动执行以控制生命周期)
请注意,使用 DI 接口的主要目的是能够交换实现,因此如果您的应用程序实际上没有在一个相同的数据库中交换schema 对于另一个,在这种情况下你可能不需要接口。
我设法通过更改注册以显式传递连接字符串名称来实现此功能:
UnityContainer container = new UnityContainer();
container.RegisterType<IMyDbContext, MyDbContext>(new InjectionConstructor("MainConnectionString"));
. . .
container.RegisterInstance<IUnityContainer>(container);
在尝试解析我的服务 class 时,我收到一个错误,提示无法构建 DbContext
,因为它是一个抽象 class。错误信息在这里:
Unity.Exceptions.ResolutionFailedException: 'Resolution of the dependency failed, type = 'MyService.MyClass', name = '(none)'.
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, System.Data.Common.DbConnection, is an abstract class and cannot be constructed. Are you missing a type mapping?
-----------------------------------------------
At the time of the exception, the container was:
Resolving ...
...
Resolving MyApp.MyRepository,(none)
Resolving parameter 'myDbContext' of constructor MyApp.MRepository(MyApp.IMyDbContext myDbContext)
...
Resolving parameter 'existingConnection' of constructor MyApp.MyDbContext(System.Data.Common.DbConnection existingConnection, System.Data.Entity.Infrastructure.DbCompiledModel model, System.Boolean contextOwnsConnection)
Resolving System.Data.Common.DbConnection,(none)
'
DBContext 如下所示:
public class MyDbContext : System.Data.Entity.DbContext, IMyDbContext
{
public MyDbContext()
: base("MainConnectionString")
{
}
我的猜测是 EF 在配置文件中查找连接字符串;但连接字符串已定义:
<connectionStrings>
<add name="MainConnectionString" connectionString="Server=.\SQLEXPRESS;Database=MyDB;User Id= . . ." providerName="System.Data.SqlClient" />
</connectionStrings>
统一注册:
因此,我的问题是 EF 如何计算出如何构建这个 class,显然我在配置中遗漏了一些东西。
UnityContainer container = new UnityContainer();
container.RegisterType<IMyDbContext, MyDbContext>();
container.RegisterType<IMyRepository, MyRepository>();
container.RegisterInstance<IUnityContainer>(container);
根据this answer:
Unity will resolve a concrete type (.Resolve), but interfaces have to be explicitly registered by associating them with concrete types.
那么,你有两个选择:
- 向Unity注册
IMyDbContext
接口 - 停止使用
IMyDbContext
并使用具体类型(在这种情况下 Unity 将自动解析它,尽管您可能需要手动执行以控制生命周期)
请注意,使用 DI 接口的主要目的是能够交换实现,因此如果您的应用程序实际上没有在一个相同的数据库中交换schema 对于另一个,在这种情况下你可能不需要接口。
我设法通过更改注册以显式传递连接字符串名称来实现此功能:
UnityContainer container = new UnityContainer();
container.RegisterType<IMyDbContext, MyDbContext>(new InjectionConstructor("MainConnectionString"));
. . .
container.RegisterInstance<IUnityContainer>(container);