使用额外的 ctr 统一创建 DbContext 失败

Creating DbContext with unity failing with additional ctr

我有自定义的 DbContext,它继承自 IdentityDbContext。 Class 看起来像这样:

public class ReaderContext : IdentityDbContext<IdentityUser>
{
    //DbSets

    public ReaderContext() 
        : base("name=ReaderDb")
    {
        System.Data.Entity.Database.SetInitializer<ReaderContext>(null);
        Database.Initialize(true);
    }
 }

当 DbContext 看起来像这样时,创建存储库(使用 ReaderContext)的代码工作正常:

container.RegisterType<IRepository, CustomRepository>(new HierarchicalLifetimeManager());
var repo = container.Resolve<IRepository>();

当我向 ReaderContext 添加另一个构造函数(而不是删除现有构造函数!)时,创建 CustomRepository 在 UnityContainer 中不再起作用。

    public ReaderContext(DbConnection connection)
        : base(connection, true)
    {

    }

我需要这样,所以我可以用 Effort 最小化上下文。我正在使用 Unity 容器。我遇到的异常:

2017-08-07 19:02:57.9256 : Exception : Microsoft.Practices.Unity.ResolutionFailedException: Resolution of the dependency failed, type = "DataAccess.Database.Repositores.IRepository", 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 DataAccess.Database.Repositores.CustomRepository,(none) (mapped from DataAccess.Database.Repositores.IRepository, (none))
Resolving parameter "context" of constructor DataAccess.Database.Repositores.CustomRepository(DataAccess.Database.ReaderContext context) Resolving DataAccess.Database.ReaderContext,(none) Resolving parameter "connection" of constructor DataAccess.Database.ReaderContext(System.Data.Common.DbConnection connection) Resolving System.Data.Common.DbConnection,(none) ---> System.InvalidOperationException: The current type, System.Data.Common.DbConnection, is an abstract class and cannot be constructed. Are you missing a type mapping?

为什么添加新的构造函数会破坏统一配置?另外,我尝试从头开始设置统一但无法使其工作。可能我不知道 unity 是如何工作的,所以欢迎任何提示:)

默认情况下,Unity 将 select 具有最多参数的构造函数。所以,最初使用无参数构造函数,一切都很好。

但是,当您添加 ReaderContext(DbConnection connection) 构造函数时,该构造函数现在是参数数量最多的构造函数,因此 Unity 选择使用它。对于该构造函数,Unity 认为它需要一个 DbConnection 但是,正如异常消息所示,DbConnection 是抽象的,因此 Unity 无法实例化它并且没有从抽象 DbConnection 到Unity 可以实例化的具体非抽象 class。

解决方案是明确告诉 Unity 您想要它做什么。如果你想使用无参数构造函数,你可以通过提供一个没有参数的 InjectionConstructor 来实现:

container.RegisterType<ReaderContext>(new InjectionConstructor());

如果您想使用 DbConnection 构造函数,您要么必须显式配置 Unity 如何构造 ReaderContext,要么配置 Unity 如何解析抽象 DbConnection。我通常会使用后一种方法并配置映射并让 Unity 构建对象图:

container.RegisterType<DbConnection, SqlConnection>(
   new InjectionFactory(c => new SqlConnection("connectionString")));