如何将DbContext实现注入Prism ViewModel构造函数?

时间:2015-08-05 12:31:39

标签: c# wpf entity-framework prism

我正在使用Unity和Entity Framework开发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未被用户代码处理   的HResult = -2146233088   消息=尝试获取Object类型的实例时出现激活错误,键“ProductContextResultView”   来源= Microsoft.Practices.ServiceLocation   堆栈跟踪:        at c:\ Projects \ CommonServiceLocator \ main \ Microsoft.Practices.ServiceLocation \ ServiceLocatorImplBase.cs中的Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(类型serviceType,String key):第53行        at c:\ Projects \ CommonServiceLocator \ main \ Microsoft.Practices.ServiceLocation \ ServiceLocatorImplBase.cs中的Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance [TService](字符串键):第103行        在Microsoft.Practices.Prism.Regions.RegionNavigationContentLoader.CreateNewRegionItem(String candidateTargetContract)   InnerException:Microsoft.Practices.Unity.ResolutionFailedException        的HResult = -2146233088        Message =依赖项的解析失败,type =“System.Object”,name =“ProductContextResultView”。 在解决时发生异常。

异常是:InvalidOperationException - 当前类型System.Data.Common.DbConnection是一个抽象类,无法构造。你错过了类型映射吗?

在例外时,容器是:

解析ContextResultsPane.ProductContextResult.ProductContextResultView,ProductContextResultView(从System.Object,ProductContextResultView映射)   解析构造函数ContextResultsPane.ProductContextResult.ProductContextResultView(ContextResultsPane.ProductContextResult.ProductContextResultViewModel viewModel)的参数“viewModel”     解析ContextResultsPane.ProductContextResult.ProductContextResultViewModel,(无)     解析构造函数ContextResultsPane.ProductContextResult.ProductContextResultViewModel(SharedResources.DataAccess.IDataBaseContext dataBaseContext)的参数“dataBaseContext”       解析SharedResources.DataAccess.EFDbContext,(无)(从SharedResources.DataAccess.IDataBaseContext映射,(无))       解析构造函数SharedResources.DataAccess.EFDbContext(System.Data.Common.DbConnection连接)的参数“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: 

1 个答案:

答案 0 :(得分:3)

格伦托马斯的指导帮助我指出了更多阅读,结果证明Unity默认使用最详细的构造函数。这是问题的核心,因为我有一个构造函数需要传递DbConnection进行单元测试。

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

container.RegisterType<IDataBaseContext, EFDbContext>();

......对此...

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

更改后,它按预期工作!