Unity : No parameterless constructor defined for this object. - c#

Below code is to Initialize Dependency Injection Container in application global.asax
IUnityContainer container = new UnityContainerFactory().CreateConfiguredContainer();
var serviceLocator = new UnityServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => serviceLocator);
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
But application is always failing with parameter less constructor exception for
HomeController, below is the exception.
Resolution of the dependency failed, type = "MyApp.Web.Controllers.HomeController", name = "(none)".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, Microsoft.Practices.ServiceLocation.IServiceLocator, is an interface and cannot be constructed. Are you missing a type mapping?
At the time of the exception, the container was:
Resolving MyApp.Web.Controllers.HomeController,(none)
Resolving parameter "serviceLocator" of constructor MyApp.Web.Controllers.HomeController(Microsoft.Practices.ServiceLocation.IServiceLocator serviceLocator)
Resolving Microsoft.Practices.ServiceLocation.IServiceLocator,(none)
Below is the inner exception of the exception.
at Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.ThrowForAttemptingToConstructInterface(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\BuildPlan\DynamicMethod\Creation\DynamicMethodConstructorStrategy.cs:line 207
at BuildUp_Microsoft.Practices.ServiceLocation.IServiceLocator(IBuilderContext )
at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\BuildPlan\BuildPlanStrategy.cs:line 43
at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\StrategyChain.cs:line 112
at Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\BuilderContext.cs:line 215
at BuildUp_MyApp.Web.Controllers.HomeController(IBuilderContext )
at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\BuildPlan\BuildPlanStrategy.cs:line 43
at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\StrategyChain.cs:line 112
at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs:line 511
Microsoft.Practices.Unity 2.0.414.0 has been used. What is the issue with implementation, am I missing something?

You need to register all interfaces your controller relies on. In this case
HomeController(Microsoft.Practices.ServiceLocation.IServiceLocator serviceLocator) {...}
Means you need to have line like
container.RegisterType<IServiceLocator, SomeServiceLocatorImpl>();
Note that it is generally better practice to depend on required interfaces instead on IServiceLocator - How to avoid Service Locator Anti-Pattern?

Your constructor presumably has the following signature
public class HomeController : Controller
{
public HomeController( IServiceLocator locator )
{
...
Unity follows the signature and tries to find a concrete type mapped to the interface, registered in your container. But there is none.
What you do however, is a mistake. You should be injecting actual dependencies to services / business objects, not to the infrastructure class a service locator is.
public HomeController( ISomeService service, IAnotherService another )
Unity would resolve these, assuming you first map abstractions to concrete types.

Related

System.AggregateException in Program.cs in ASP.NET Core MVC

I have an ASP.NET Core MVC application which uses Entity Framework Core O/RM. I am implementing generic repository pattern in my application. There are two entities, Employee & Department. There is one context class EmployeeDepartmentDetails.There's an interface IGenericRepository which is implemented by GenericRepository. GenericRepository has a Dependency Injection of EmployeeDepartmentDetails.My Controller EmployeeController has a Dependency Injection of IGenericRepository.
IGenericRepository.cs -
public interface IGenericRepository<TEntity> where TEntity : class
{
//...
}
GenericRepository.cs - Here EmployeeDepartmentDetails is my context class which inherits DBContext class-
public class GenericRepository<TEntity> :IGenericRepository<TEntity> where TEntity : class
{
DbSet<TEntity> _dbSet;
// Dependency Injection
private readonly EmployeeDepartmentDetail _employeeDepartmentDetail;
public GenericRepository(EmployeeDepartmentDetail employeeDepartmentDetail)
{
_employeeDepartmentDetail = employeeDepartmentDetail;
_dbSet = _employeeDepartmentDetail.Set<TEntity>();
}
//...
}
Program.cs -
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run(); // I am getting those two exceptions here
}
StartUp.cs -
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddScoped(typeof(IGenericRepository<Type>), typeof(GenericRepository<Type>));
}
EmployeeController.cs -
public class EmployeeController : Controller
{
private readonly IGenericRepository<Employee> _genericRepository;
public EmployeeController(IGenericRepository<Employee> genericRepository)
{
_genericRepository = genericRepository;
}
//...
}
I am getting two exception, when I am running my application -
System.AggregateException
HResult=0x80131500
Message=Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: InfrastructureLayer.GenericRepository.Interface.IGenericRepository1[System.Type] Lifetime: Scoped ImplementationType: InfrastructureLayer.GenericRepository.Implementation.GenericRepository1[System.Type]': A suitable constructor for type 'InfrastructureLayer.GenericRepository.Implementation.GenericRepository1[System.Type]' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.)
Source=Microsoft.Extensions.DependencyInjection
StackTrace:at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable1 serviceDescriptors, ServiceProviderOptions options) at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options) at Microsoft.Extensions.DependencyInjection.DefaultServiceProviderFactory.CreateServiceProvider(IServiceCollection containerBuilder) at Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter`1.CreateServiceProvider(Object containerBuilder) at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider() at Microsoft.Extensions.Hosting.HostBuilder.Build() at CrudEfCore.Program.Main(String[] args) in C:\Users\singh\Desktop\MVC\GenericRepository\CrudEfCore\Program.cs:line 16
This exception was originally thrown at this call stack:[External Code]
Inner Exception 1:
InvalidOperationException: Error while validating the service descriptor 'ServiceType: InfrastructureLayer.GenericRepository.Interface.IGenericRepository1[System.Type] Lifetime: Scoped ImplementationType: InfrastructureLayer.GenericRepository.Implementation.GenericRepository1[System.Type]': A suitable constructor for type 'InfrastructureLayer.GenericRepository.Implementation.GenericRepository`1[System.Type]' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.
Inner Exception 2:
InvalidOperationException: A suitable constructor for type 'InfrastructureLayer.GenericRepository.Implementation.GenericRepository`1[System.Type]' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.
I am unable to understand the exception, I don't know what I am doing wrong here. I know I have pasted lot of code, but I don't even know how to explain the exception.
This is the cause of the issue
services.AddScoped(typeof(IGenericRepository<Type>), typeof(GenericRepository<Type>));
Type is an abstract class and as the error message states:
Ensure the type is concrete and services are registered for all parameters of a public constructor.
note: emphasis mine
Next Type is not what you should be using as the generic argument when registering the generic service
In this case you can register using (generic) open types, eliminating the need to register every (generic) constructed type:
services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>));
Reference Dependency injection in ASP.NET Core

Which types should I register with my IOC container for Umbraco ContentService to be instantiated?

One of the classes in my Umbraco project depends on IContentService. I'm trying to provide an IContentService to this class with an IOC container.
Here is how I'm registering IContentService with my IOC (Autofac)
builder.RegisterType<Umbraco.Core.Services.ContentService>().As<IContentService>();
However, Umbraco.Core.Services.ContentService requires these constructor parameters:
public ContentService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory, IPublishingStrategy publishingStrategy, IDataTypeService dataTypeService, IUserService userService);
Autofac gets stuck because it doesn't know about any of these types yet. Here's a stack trace:
Exception Details: Autofac.Core.DependencyResolutionException: None of the constructors found with
'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'Umbraco.Core.Services.ContentService' can be
invoked with the available services and parameters:Cannot resolve parameter
'Umbraco.Core.Persistence.RepositoryFactory repositoryFactory' of constructor 'Void
.ctor(Umbraco.Core.Persistence.UnitOfWork.IDatabaseUnitOfWorkProvider, Umbraco.Core.Persistence.RepositoryFactory,
Umbraco.Core.Logging.ILogger, Umbraco.Core.Events.IEventMessagesFactory, Umbraco.Core.Publishing.IPublishingStrategy,
Umbraco.Core.Services.IDataTypeService, Umbraco.Core.Services.IUserService)'.
Which types should I register with Autofac so that my ContentService can be instantiated?
Here's how I solved this particular problem. Thanks to Claus for the help.
I need to use RegisterInstance() (docs here) instead of RegisterType<T>()
public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
var builder = new ContainerBuilder();
// Register the components we need resolving with Autofac
builder.RegisterInstance(applicationContext.Services.MemberService).As<IMemberService>();
builder.RegisterInstance(applicationContext.Services.ContentService).As<IContentService>();
// ... Configuration for dependency resolution here ...
}
The reason for this is that Umbraco creates an instance of ContentService and configures it correctly. Autofac needs to be told to use this instance instead of trying to create it's own.

MVC - IoC Unity - Make sure that the controller has a parameterless public constructor

Problem
I'm using Unity as IoC and that worked fine, but as I keep adding functionality, it becomes increasingly difficult to pinpoint any errors, because Unity provides an error that is the symptom of the error, not the actual error:
"Message":"An error has occurred.","ExceptionMessage":"An error occurred
when trying to create a controller of type 'MyController'. Make sure that the
controller has a parameterless public
constructor.","ExceptionType":"System.InvalidOperationException"
Background
I have an MVC Web Api controller that has a dependency on a Manager instance (from domain):
public class MyController : ApiController
{
private IMyManager MyManager { get; set; }
public MyController(IMyManager myManager)
{
this.MyManager = myManager;
}
...
}
The above error occurs because IoC mapping of the IMyManager fails. As it fails, I have no parameter, meaning that MyController is called using a parameterless constructor, but since it doesn't exist (and shouldn't) I get the above error.
What I have tried
So, the error I get is not the 'real' error. The obvious thing is to make sure that every new implementation is registered under IoC, I checked and they are. I do it manually to keep things manageable (oh the irony!).
I do that like this:
container.RegisterType<IMyManager, MyManager>();
But, that's not the issue.
One fix I did was a circular dependency. I changed all involved constructors and methods to use property values, not instances.
I checked all involved classes and there are no longer any circular dependencies.
Yet, the problem still occurs.
The question
What can I do to find out the actual problem? Manually checking dependencies is way too much overhead, because the structure is an intricate web of deeper dependencies. And this will get worse as the app matures.
Alternatively, if Unity just always obscures these messages (without being able to fix that), are there alternatives out there that do provide worthwhile error information?
UPDATE
Per request, the full error message (though I don't think the stacktrace is very helpful):
{"Message":"An error has occurred.","ExceptionMessage":"An error occurred when trying to create a controller of type 'MyController'. Make sure that the controller has a parameterless public constructor.","ExceptionType":"System.InvalidOperationException","StackTrace":" at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()","InnerException":{"Message":"An error has occurred.","ExceptionMessage":"Type 'MyProject.Web.Api.Controllers.MyController' does not have a default constructor","ExceptionType":"System.ArgumentException","StackTrace":" at System.Linq.Expressions.Expression.New(Type type)
at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)"}}
UPDATE 2
I dug a little deeper and checked all dependencies (they are pretty massive), but everything is registered and loaded correctly. There also aren't any circular dependencies, so as far as I can tell everything 'should' work. Since it doesn't I conclude that there's some error happening that is not being thrown up.
If the error says that you need a parameterless constructor, that suggests to me that Unity isn't registered for WebAPI, even though it is registered for your ASP.NET MVC application. If your IoC is working correctly, it shouldn't need a paramaterless constructor, because it should be able to resolve the dependencies that exist within your controller's constructor.
WebAPI has it's own pipeline to ASP.NET MVC for example WebAPI can be OWIN hosted, hence why it needs hooking up separately even if they exist in the same project.
You should hook your WebAPI to the dependency resolver within your UnityConfig, I believe that there is an example here: http://www.devtrends.co.uk/blog/using-unity.mvc5-and-unity.webapi-together-in-a-project
using Microsoft.Practices.Unity;
using System.Web.Http;
using System.Web.Mvc;
namespace WebApplication1
{
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
// register all your components with the container here
// it is NOT necessary to register your controllers
// e.g. container.RegisterType<ITestService, TestService>();
// Configures container for ASP.NET MVC
DependencyResolver.SetResolver(new Unity.Mvc5.UnityDependencyResolver(container));
// Configures container for WebAPI
GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
}
}
}
In the example above there are two lines for configuration, but they share the same container and thus the same bindings - you don't have to define them twice. If you ever came to separate the WebAPI project from the ASP.NET MVC one, then you would have to have a separate container and bindings.
In terms of finding the problem, or Unity hiding errors from you, in my experience this simply isn't the case. The error that you're experiencing is straight from ASP.NET MVC. In normal use without an IoC, you need a parameterless constructor... with an IoC it controls the creation of the controllers and thus resolves the dependencies.
I found it, the problem was that I am remaking existing code, in the same solution, meaning that there's going to be duplicate files with identical names.
In this particular case I had an interface that was exactly the same as a previously existing one. Somewhere deep in the code I used the wrong namespace, meaning that the IoC mapping was incorrect.
So, something like this:
I have:
old.managers.IMyManager
and
new.managers.IMyManager
What I was doing in the mapping was:
container.RegisterType<IMyManager, MyManager>();
where IMyManager in this case is new.managers.IMyManager, as it should be.
One of the consumers of this dependency expected IMyManager of namespace old.managers.
Updating the consumer to use the new namespace fixed it.
Don't forget this in your web.config
<system.web>
<compilation targetFramework="4.8" />
<httpRuntime targetFramework="4.8" />
<customErrors mode="Off" />
</system.web>
Missing the httpRuntime targetFramework="4.8" part will cause the parameterless public constructor error
I think you should add another constructor for your controller.
public MyController() {}
If it still error, you should check the components that register for Application_Start (in Global.asax). In UnityConfig.cs :
public static void RegisterComponents()
{
var container = new UnityContainer();
container.RegisterType<IMyManager, MyManager>();
MvcUnityContainer.Container = container;
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
Make the default for controller.
public class UnityControllerFactory : DefaultControllerFactory
{
public override IController CreateController(RequestContext requestContext, string controllerName)
{
Type controllerType = null;
if (TypeHelper.LooksLikeTypeName(controllerName))
{
controllerType = TypeHelper.GetType(controllerName);
}
if (controllerType == null)
{
controllerType = this.GetControllerType(requestContext, controllerName);
}
return controllerType != null ? this.GetControllerInstance(requestContext, controllerType) : null;
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
try
{
if (controllerType == null)
throw new ArgumentNullException("controllerType");
if (!typeof(IController).IsAssignableFrom(controllerType))
throw new ArgumentException(string.Format(
"Type requested is not a controller: {0}",
controllerType.Name),
"controllerType");
return MvcUnityContainer.Container.Resolve(controllerType) as IController;
}
catch
{
return null;
}
}
}
public static class MvcUnityContainer
{
public static IUnityContainer Container { get; set; }
}
In Application_Start() (Global.asax.cs and Global.asax)
UnityConfig.RegisterComponents();

StructureMap thinks it has to inject to constructor and throws exception

I'm using StructureMap and ASP.Net Identity in my application. When I have this line in my Application_Start
ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
and this is StructureMapControllerFactory:
public class StructureMapControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null && requestContext.HttpContext.Request.Url != null)
throw new InvalidOperationException(string.Format("Page not found: {0}",
requestContext.HttpContext.Request.Url.AbsoluteUri.ToString(CultureInfo.InvariantCulture)));
return ObjectFactory.GetInstance(controllerType) as Controller;
}
}
return ObjectFactory.GetInstance(controllerType) as Controller; throws a StructureMapConfigurationException exception saying:
No default Instance is registered and cannot be automatically determined for type 'IUserStore<Person>'
but if I remove ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory()); line everything goes fine so it's StructureMap's problem not my code.
I think the exception is clear. It's probably about the AccountController from the Identity template, which comes with 2 constructors.
StructureMap will use the most greediest constructor by default. The template comes with 2 constructors, one default constructor and one constructor with an ApplicationUserManager object.
Without StructureMap the default constructor is called and the ApplicationUserManager will be resolved using the service locator anti pattern.
StructureMap now must create the ApplicationUserManager and because this is a concrete type it will try. If it was an abstract it will throw the exception right there. The ApplicationUserManager however has a single constructor which needs an IUserStore<Person>. Because this is an abstract and the container has no registration of this type, StructureMap is unable to create the type for you.
To solve this you should remove the default constructor and Register the ApplicationUserManager and depending services which is at least some component which, implements IUserStore.
Edit:
While the solution you mentioned in the comments may work, this is not the preferable solution because of:
Having multiple constructors is an anti-pattern
You are now using the service locator anti pattern for resolving the ApplicationUserManager from the HttpContext
The templates that come with VS2013 need some work to use with dependency injection. This will cost some time. The good news is, it is possible and doable and will greatly improve your knowledge of Owin, Asp.Net Identity, Dependency Injection and SOLID design.
There are several blogs on how to start refactoring the templates to work with dependency injection. You could read about that here and here

ResolutionFailedException with Unity

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.
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.
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>();
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.

Categories