The type String cannot be constructed. You must configure the container to supply this value
Solution 1
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)
Solution 2
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.
user2023116
Updated on June 08, 2022Comments
-
user2023116 almost 2 years
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.
-
user2023116 over 8 yearsMy context isn't in my mapping. The only mapping I have is from IStateService to StateService. Am I misunderstanding what you meant?
-
Alexei Levenkov over 8 years@user2023116 by default Unity registers all types so it tries to create instance of
MyAppDbContext
(as it is implicitly registred) when callingStateService(MyAppDbContext context)
. I assumeMyAppDbContext
has some string parameter for constructor (and hence fail to resolve). -
user2023116 over 8 years@AlexeiLevenkov How do I keep my context out of my DI mappings if it is implicitly registered? Do I inject an interface of my context to the service?
-
vidalsasoon over 8 yearsgeneral rule: don't inject anything in your constructors unless it's an interface. Remove "MyAppDbContext context" from your StateService ctor and it should be good. If you need your context, use it like here: msdn.microsoft.com/en-ca/data/jj729737.aspx. basically, don't inject your EF context because it's a can of worms. keep it hidden in your services.
-
user2023116 over 8 yearsThere has to be a way of doing this without the using statements. I don't necessarily want my context closed after each method call, so that I can utilize I queryable and lazy loading. I am able to get this to work with AutoFac, but I don't understand why this simple example isn't working like some of the Unity tutorials.I appreciate the help you guys have given so far, but so far I can't consider those solutions.
-
Alexei Levenkov over 8 years@user2023116 you should ask separate question on that. Also before doing so make sure you understand lifetime of each dependency involved (like "I want context to live for single web request").
-
user2023116 over 8 years@AlexeiLevenkov "The default behavior of DbContext is that the underlying connection is automatically opened any time is needed and closed when it is no longer needed". See this link