3

我正在使用 Patterns and Practices 的 Unity 将依赖项注入到我的对象中,并且遇到了一个奇怪的(无论如何对我来说)问题。这是我的类定义:

public class ImageManager : IImageManager 
{
    IImageFileManager fileManager;

    public ImageManager(IImageFileManager fileMgr)
    {
        this.fileManager = fileMgr;

    }
}

public class ImageFileManager : IImageFileManager
{
    public ImageFileManager(string folder)
    {
        FileFolder = folder;
    }
 }

这是注册我的课程的代码

container.RegisterInstance<MainWindowViewModel>(new MainWindowViewModel())
         .RegisterType<IPieceImageManager, PieceImageManager>(
              new InjectionConstructor(typeof(string)))
         .RegisterType<IImageFileManager, ImageFileManager>()
         .RegisterType<IImageManager, ImageManager>(
              new InjectionConstructor(typeof(IImageFileManager)));

我最初在这样的 XAML 文件后面的代码中解决了这个问题(我知道,它违背了目的。请耐心等待。)

IImageManager imageManager = MvvmViewModelLocator.Container.Resolve<IImageManager>(
    new ParameterOverride("folder", "/images"));

它奏效了。但是我为我的主视图创建了一个视图模型,当我将同一行复制到其中时,我得到了一个异常。这是两个最内在的例外:

InnerException: Microsoft.Practices.Unity.ResolutionFailedException
  HResult=-2146233088
  Message=Resolution of the dependency failed, type = "SwapPuzzleApp.Model.IImageManager", name = "(none)".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The type IImageManager does not have an accessible constructor.

At the time of the exception, the container was:

Resolving SwapPuzzleApp.Model.IImageManager,(none)

        Source=Microsoft.Practices.Unity
        TypeRequested=IImageManager
        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.Unity.UnityContainerExtensions.Resolve[T](IUnityContainer container, ResolverOverride[] overrides)
             at SwapPuzzleApp.ViewModel.MainWindowViewModel..ctor() in c:\Users\Carole\Documents\Visual Studio 2012\Projects\SwapPuzzle\SwapPuzzle\ViewModel\MainWindowViewModel.cs:line 17
             at SwapPuzzleApp.ViewModel.MvvmViewModelLocator..cctor() in c:\Users\Carole\Documents\Visual Studio 2012\Projects\SwapPuzzle\SwapPuzzle\ViewModel\MvvmViewModelLocator.cs:line 51
        InnerException: System.InvalidOperationException
             HResult=-2146233079
             Message=The type IImageManager does not have an accessible constructor.
             Source=Microsoft.Practices.Unity
             StackTrace:

             StackTrace:
                  at Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.ThrowForNullExistingObject(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: 

我不确定问题是什么,因为 ImageManager 显然有一个公共构造函数。我认为这可能是由于路径无效,但如果我具体实例化该对象,一切正常。

// this line has no problems
IImageManager imageManager = new ImageManager(new ImageFileManager("/images"));  

我还想知道在注册 IImageManager 时是否需要传入 new InjectionConstructor(typeof(string)),但这似乎没有帮助,为什么现在需要它而不是以前需要它?所以我很难过。这是我第一次尝试使用依赖注入,所以它可能是一些基本的东西。不过,我只是没有看到什么。

4

3 回答 3

6

仔细查看错误消息。注意这部分:

 Message=The type IImageManager does not have an accessible constructor.

请注意,类型名称是 IImageManager,而不是ImageManager。在某个地方,您丢失了类型映射。

你的 FileImageManager 注册也有问题,因为你没有在注册中指定文件夹参数,所以 Unity 不知道要传递什么字符串。

于 2013-07-12T06:57:41.307 回答
4

我使用本文中的示例作为我的指南。要么其中的示例太高级而无法进行介绍,要么该主题中存在错误信息。

在咨询了其他来源(主要是 PluarlSight)后,我想出了一个更简单、更合乎逻辑的解决方案。

container.RegisterInstance<TimerViewModel>(new TimerViewModel());
container.RegisterType<IPieceImageManager, PieceImageManager>();
container.RegisterType<IImageFileManager, ImageFileManager>
    (new InjectionConstructor("/images"));
container.RegisterType<IImageManager, ImageManager>();
于 2013-11-19T01:43:22.600 回答
0

我遇到了一个类似的问题,这个错误直接与我为手术做的 Mock(使用 automoq)相关。在这种情况下,事实证明,因为有许多成员方法会被模拟的对象调用,所以我必须在 automoq 链中定义所有这些方法才能正确解析

我意识到这是实例代码中的一个示例,但它也可能出现在 Moqs 中。因此,如果您阅读本文并想知道与 Moqs 相关的示例,请先查看该示例。

于 2021-11-08T15:17:46.033 回答