3

I'm using Patterns and Practices' Unity to inject dependencies into my objects and have hit a weird (to me, anyway) issue. Here's my class definitions:

public class ImageManager : IImageManager 
{
    IImageFileManager fileManager;

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

    }
}

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

And here's the code to register my classes

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

I originally resolved this in the code behind (I know, it defeats the purpose. Bear with me.) of the XAML file like this

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

And it worked. But I created a view model for my main view and when I copied the same line into it, I get an exception. Here are the two most inner exceptions:

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: 

I'm not sure what the problem is, as ImageManager clearly has a public constructor. I thought it might be due to an invalid path, but if I concretely instantiate the object, everything works.

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

I also wondered if I needed to pass in new InjectionConstructor(typeof(string)) when I register IImageManager, but it doesn't seem to help and why would it be needed now and not before? So I'm stumped. This is my first attempt at using Dependency Injection, so it's probably something basic. I'm just not seeing what, though.

3
  • 1
    You are resolving IImageManager and passing in parameter to the contructor called "folder" of type string. But ImageManager doesn't have a constructor that matches that definition; ImageManager's contructor accepts IImageFileManager. Commented Jul 9, 2013 at 1:50
  • Hm. That did look a bit odd, but it worked when I put it in MainWindow.xaml.cs, so I assumed the line is correct. Any guesses about why it would work in one file and not another? Commented Jul 9, 2013 at 22:57
  • 2
    I left this alone for several months and finally returned to it. I see now that I was doing things very, very wrong. Commented Nov 19, 2013 at 1:30

3 Answers 3

6

Look very closely at the error message. Notice this part:

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

Notice the type name is IImageManager, not ImageManager. Somewhere along the line you lost your type mapping.

Your registration of FileImageManager has a problem as well, since you don't specify the folder parameter in the registration, so Unity has no idea what string to pass.

Sign up to request clarification or add additional context in comments.

1 Comment

I had the following error with Unity: "Unity Resolution failed with error: No public constructor is available for type ...". This answer was just the hint I needed to figure out what was wrong. All the types injected into the class constructor were registered in Unity, and so were their dependencies. But the class I was trying to construct wasn't!
5

I was using the examples in this article as my guide. Either the examples in there are way too advanced for an introduction, or there's misinformation in that topic.

After consulting other sources (mainly PluarlSight), I came up with a much simpler and more logical solution.

container.RegisterInstance<TimerViewModel>(new TimerViewModel());
container.RegisterType<IPieceImageManager, PieceImageManager>();
container.RegisterType<IImageFileManager, ImageFileManager>
    (new InjectionConstructor("/images"));
container.RegisterType<IImageManager, ImageManager>();

Comments

0

I ran into a similar issue with this error tied directly to a Mock (using automoq) that I was doing for an operation. In this case it turned out that because there were a number of member methods that get called with the object being mocked, that I had to define all of those in the automoq chain to get it to resolve properly

I realize this is an example in instance code, but it could occur in Moqs also. So if you read this and are wondering about an example related to Moqs, look into that first.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.