Search code examples
c#asp.net-mvcentity-frameworkasp.net-mvc-5unity-container

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.


Solution

  • 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)