【问题标题】:How to inject DbContext implementation into Prism ViewModel constructor?如何将 DbContext 实现注入 Prism ViewModel 构造函数?
【发布时间】:2015-10-28 05:39:20
【问题描述】:

我正在使用 Unity 和实体框架开发 WPF Prism 应用程序。我希望在构建 ViewModel 时注入我的自定义 DbContext,这样我就可以在 ViewModel 的整个生命周期中使用它。 DbContext 类所在的模块在 Bootstrapper 中注册,DbContext 类型在 Module.Initialize() 期间注册。

话虽如此,在尝试构造注入 DbContext 的 ViewModel 时会引发运行时错误。就是说需要注册IDbConnection。当我向模块注册它时,它会说 DbConnection 是一个抽象类,无法构造。关于 DbContext 应该如何注册,一定有一些我不知道的事情。

这是在模块中注册类型的位置:

public class SharedResourcesModule : IModule
{
    IUnityContainer container;


    public SharedResourcesModule(IUnityContainer container)
    {
        this.container = container;
    }


    public void Initialize()
    {
        container.RegisterType<IAuthenticationService, AuthenticationService>();
        container.RegisterType<IDataBaseContext, EFDbContext>();
    }
}

还有一个 ViewModel 构造函数的例子:

public class ProductContextResultViewModel : ViewModelBase
{
    public ProductContextResultViewModel(IDataBaseContext dataBaseContext)
    {
        this.DataBaseContext = dataBaseContext as EFDbContext;
    }


    private EFDbContext DataBaseContext { get; set; }
}

如果我可以提供任何其他详细信息,请告诉我!

以下异常详情

Microsoft.Practices.ServiceLocation.ActivationException 未被用户代码处理 H结果=-2146233088 消息=尝试获取类型对象实例时发生激活错误,键“ProductContextResultView” 来源=Microsoft.Practices.ServiceLocation 堆栈跟踪: 在 Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) in c:\Projects\CommonServiceLocator\main\Microsoft.Practices.ServiceLocation\ServiceLocatorImplBase.cs:line 53 在 Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance[TService](String key) in c:\Projects\CommonServiceLocator\main\Microsoft.Practices.ServiceLocation\ServiceLocatorImplBase.cs:line 103 在 Microsoft.Practices.Prism.Regions.RegionNavigationContentLoader.CreateNewRegionItem(字符串候选目标合同) 内部异常:Microsoft.Practices.Unity.ResolutionFailedException H结果=-2146233088 消息=依赖项解析失败,类型 =“System.Object”,名称 =“ProductContextResultView”。 异常发生时:解决时。

异常是:InvalidOperationException - 当前类型 System.Data.Common.DbConnection 是一个抽象类,无法构造。您是否缺少类型映射?

发生异常时,容器为:

解析 ContextResultsPane.ProductContextResult.ProductContextResultView,ProductContextResultView(映射自 System.Object, ProductContextResultView) 解析构造函数 ContextResultsPane.ProductContextResult.ProductContextResultView(ContextResultsPane.ProductContextResult.ProductContextResultViewModel viewModel) 的参数“viewModel” 解决 ContextResultsPane.ProductContextResult.ProductContextResultViewModel,(none) 解析构造函数 ContextResultsPane.ProductContextResult.ProductContextResultViewModel(SharedResources.DataAccess.IDataBaseContext dataBaseContext) 的参数“dataBaseContext” 解析 SharedResources.DataAccess.EFDbContext,(none) (映射自 SharedResources.DataAccess.IDataBaseContext, (none)) 解析构造函数 SharedResources.DataAccess.EFDbContext(System.Data.Common.DbConnection connection) 的参数“connection” 正在解析 System.Data.Common.DbConnection,(无)

   Source=Microsoft.Practices.Unity
   NameRequested=ProductContextResultView
   TypeRequested=Object
   StackTrace:
        at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides)
        at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, String name, IEnumerable`1 resolverOverrides)
        at Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name, ResolverOverride[] resolverOverrides)
        at Microsoft.Practices.Prism.UnityExtensions.UnityServiceLocatorAdapter.DoGetInstance(Type serviceType, String key)
        at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) in c:\Projects\CommonServiceLocator\main\Microsoft.Practices.ServiceLocation\ServiceLocatorImplBase.cs:line 49
   InnerException: System.InvalidOperationException
        HResult=-2146233079
        Message=The current type, System.Data.Common.DbConnection, is an abstract class and cannot be constructed. Are you missing a type mapping?
        Source=Microsoft.Practices.Unity
        StackTrace:
             at Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.ThrowForAttemptingToConstructAbstractClass(IBuilderContext context)
             at lambda_method(Closure , IBuilderContext )
             at Microsoft.Practices.ObjectBuilder2.DynamicBuildPlanGenerationContext.<>c__DisplayClass1.<GetBuildMethod>b__0(IBuilderContext context)
             at Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context)
             at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)
             at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
             at Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey)
             at Microsoft.Practices.Unity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context)
             at lambda_method(Closure , IBuilderContext )
             at Microsoft.Practices.ObjectBuilder2.DynamicBuildPlanGenerationContext.<>c__DisplayClass1.<GetBuildMethod>b__0(IBuilderContext context)
             at Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context)
             at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)
             at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
             at Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey)
             at Microsoft.Practices.Unity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context)
             at lambda_method(Closure , IBuilderContext )
             at Microsoft.Practices.ObjectBuilder2.DynamicBuildPlanGenerationContext.<>c__DisplayClass1.<GetBuildMethod>b__0(IBuilderContext context)
             at Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context)
             at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)
             at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
             at Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey)
             at Microsoft.Practices.Unity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context)
             at lambda_method(Closure , IBuilderContext )
             at Microsoft.Practices.ObjectBuilder2.DynamicBuildPlanGenerationContext.<>c__DisplayClass1.<GetBuildMethod>b__0(IBuilderContext context)
             at Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context)
             at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)
             at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
             at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides)
        InnerException: 

【问题讨论】:

  • 似乎在尝试解析 DbContext 时,Unity 正在使用需要 DbConnection 的构造函数。 Unity 需要知道您要使用哪个 DbConnection 实现。
  • 你是对的,有一个DbContext的构造函数传入一个DbConnection;我完全忘记了我添加了它!经过更多阅读后发现 Unity 使用了最冗长的构造函数,尽管我希望它使用默认构造函数。谢谢!

标签: c# wpf entity-framework prism


【解决方案1】:

Glen Thomas 的指导帮助我进行了更多阅读,事实证明 Unity 默认使用最冗长的构造函数。这是问题的核心,因为我有一个构造函数,需要传递一个 DbConnection 才能进行单元测试。

为了强制 Unity 使用默认构造函数,我更改了这个...

container.RegisterType<IDataBaseContext, EFDbContext>();

...到这个...

container.RegisterType<IDataBaseContext, EFDbContext>(new InjectionConstructor());

更改后它按预期工作!

【讨论】:

    猜你喜欢
    • 2019-10-09
    • 1970-01-01
    • 2017-07-31
    • 1970-01-01
    • 1970-01-01
    • 2020-07-28
    • 1970-01-01
    • 2019-12-28
    • 2021-12-23
    相关资源
    最近更新 更多