Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The type String cannot be constructed. You must configure the container to supply this value

I have looked at several tutorials and stackoverflow questions on how to implement unity for an MVC 5 project, but I can't seem to get past this error :

The type String cannot be constructed. You must configure the container to supply this value.

I installed the NuGet package Unity.Mvc5, and registered my type in the unity config. I have also called the register components method in the unityconfig file.

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>();
        container.RegisterType<IStateService, StateService>();

        DependencyResolver.SetResolver(new UnityDependencyResolver(container));
    }
}

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    UnityConfig.RegisterComponents();
}

public class StateController : Controller
{
    private readonly IStateService stateService;

    public StateController(IStateService stateService)
    {
        this.stateService = stateService;
    }

    // GET: /State/
    public ActionResult Index()
    {
        return View(stateService.GetStates());
    }
}

public interface IStateService : IDisposable
{
    IEnumerable<State> GetStates();
}

public class StateService : IStateService
{
    private MyAppDbContext context;
    public StateService() : this(new MyAppDbContext()){}

    public StateService(MyAppDbContext context)
    {
        this.context = context;
    }

    private IQueryable<State> All()
    {
        return context.States;
    }

    public IEnumerable<State> GetStates()
    {
        return this.All().ToList();           
    }

    public void Dispose()
    {
        context.Dispose();
    }
}

Here is the stack trace:


[InvalidOperationException: The type String cannot be constructed. You must configure the container to supply this value.]
   Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.GuardTypeIsNonPrimitive(IBuilderContext context) +311
   Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.PreBuildUp(IBuilderContext context) +229
   Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +274
   Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlanCreatorPolicy.CreatePlan(IBuilderContext context, NamedTypeBuildKey buildKey) +162
   Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) +245
   Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +274
   Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey) +250
   Microsoft.Practices.Unity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context) +101
   lambda_method(Closure , IBuilderContext ) +215
   Microsoft.Practices.ObjectBuilder2.c__DisplayClass1.b__0(IBuilderContext context) +71
   Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context) +42
   Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) +333
   Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +274
   Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey) +250
   Microsoft.Practices.Unity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context) +101
   lambda_method(Closure , IBuilderContext ) +205
   Microsoft.Practices.ObjectBuilder2.c__DisplayClass1.b__0(IBuilderContext context) +71
   Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context) +42
   Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) +333
   Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +274
   Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey) +250
   Microsoft.Practices.Unity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context) +101
   lambda_method(Closure , IBuilderContext ) +209
   Microsoft.Practices.ObjectBuilder2.c__DisplayClass1.b__0(IBuilderContext context) +71
   Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context) +42
   Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) +333
   Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +274
   Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides) +383

[ResolutionFailedException: Resolution of the dependency failed, type = "MyApp.MVC.Controllers.StateController", name = "(none)".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The type String cannot be constructed. You must configure the container to supply this value.
-----------------------------------------------
At the time of the exception, the container was:

  Resolving MyApp.MVC.Controllers.StateController,(none)
  Resolving parameter "stateService" of constructor MyApp.MVC.Controllers.StateController(MyApp.Service.Services.IStateService stateService)
    Resolving MyApp.Service.Services.StateService,(none) (mapped from MyApp.Service.Services.IStateService, (none))
    Resolving parameter "context" of constructor MyApp.Service.Services.StateService(MyApp.Data.DAL.MyAppDbContext context)
      Resolving MyApp.Data.DAL.MyAppDbContext,(none)
      Resolving parameter "connectionString" of constructor MyApp.Data.DAL.MyAppDbContext(System.String connectionString, System.Data.Entity.Infrastructure.DbCompiledModel model)
        Resolving System.String,(none)
]
   Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides) +446
   Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, String name, IEnumerable`1 resolverOverrides) +50
   Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name, ResolverOverride[] resolverOverrides) +48
   Microsoft.Practices.Unity.UnityContainerExtensions.Resolve(IUnityContainer container, Type t, ResolverOverride[] overrides) +61
   Unity.Mvc5.UnityDependencyResolver.GetService(Type serviceType) +140
   System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +87

[InvalidOperationException: An error occurred when trying to create a controller of type 'MyApp.MVC.Controllers.StateController'. Make sure that the controller has a parameterless public constructor.]
   System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +247
   System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +438
   System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +257
   System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +326
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +157
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +88
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +50
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

What might I be doing wrong?

UPDATE

I added the following code to the RegisterComponents method in the UnityConfig class and it seems to be working:

container.RegisterInstance<StateService>(new StateService());

None of the tutorials show a need for this, and I feel like my example case that I'm using it pretty standard. Why would I need that line? I don't know too much about Unity yet, so that is why I am still curious.

like image 843
user2023116 Avatar asked Sep 25 '15 16:09

user2023116


2 Answers

I didn't see this answer anywhere, so I wanted to add this too. What it looks like to me is you have multiple constructors on your StateService object. So, Unity is picking the constructor with the most parameters (as was mentioned in the comments).

You call tell Unity which constructor to use using InjectionConstructor.

Below tells it to use the parameterless constructor.

container.RegisterType<IStateService, StateService>(new InjectionConstructor());

or you could also tell it to use one with a type as well.

container.RegisterType<IStateService, StateService>(new InjectionConstructor(<some type>))

This will you force Unity to use the constructor that you want.

like image 102
Cory Avatar answered Sep 24 '22 20:09

Cory


Your StateService is trying to resolve "context". I would recommend that you keep your context out of the DI mappings so keep it out of constructors that you want to resolve.

Resolving parameter "context" of constructor MyApp.Service.Services.StateService(MyApp.Data.DAL.MyAppDbContext context)
like image 31
vidalsasoon Avatar answered Sep 23 '22 20:09

vidalsasoon