3

Я смотрел на несколько учебников и StackOverflow вопросы о том, как реализовать единство для проекта MVC 5, но я не могу пройти мимо этой ошибки:Тип String не может быть сконструирован. Вы должны настроить контейнер поставить это значение

Строка типа не может быть построена. Вы должны настроить контейнер для подачи этого значения.

Я установил пакет NuGet Unity.Mvc5 и зарегистрировал свой тип в конфигурации единства. Я также назвал метод компонентов регистров в файле unityconfig.

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

Вот трассировки стека:


[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

Что может я делать неправильно?

UPDATE

Я добавил следующий код метода RegisterComponents в классе UnityConfig и это, кажется, работает:

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

Ни один из учебников не показывают необходимость этого, и я чувствую, что пример моего примера, что я использую его довольно стандартно. Зачем мне нужна эта линия? Я еще не слишком много знаю о Единстве, поэтому мне все еще интересно.

+0

Когда/где происходит эта ошибка? –

+0

Я просто добавил трассировку стека, но это происходит в StateController. – user2023116

+0

Как выглядит код для StateService? – Jasen

ответ

4

Ваш StateService пытается разрешить «контекст». Я бы порекомендовал вам сохранить ваш контекст из сопоставлений DI, чтобы он не содержал конструкторы, которые вы хотите разрешить.

Resolving parameter "context" of constructor MyApp.Service.Services.StateService(MyApp.Data.DAL.MyAppDbContext context) 
+0

Мой контекст не в моем сопоставлении. Единственное отображение, которое у меня есть, - от IStateService до StateService. Неужели я не понимаю, что вы имели в виду? – user2023116

+1

@ user2023116 по умолчанию Unity регистрирует все типы, поэтому пытается вызвать экземпляр 'MyAppDbContext' (поскольку он неявно зарегистрирован) при вызове' StateService (контекст MyAppDbContext) '. Я полагаю, что 'MyAppDbContext' имеет некоторый строковый параметр для конструктора (и, следовательно, не может быть разрешен). –

+0

@AlexeiLevenkov Как я могу сохранить свой контекст вне своих сопоставлений DI, если он неявно зарегистрирован? Включить ли я интерфейс моего контекста в службу? – user2023116

3

Я не видел этого ответа нигде, поэтому я хотел добавить это тоже. Как мне кажется, у вас есть несколько конструкторов для объекта StateService. Итак, Unity выбирает конструктор с наибольшим количеством параметров (как упоминалось в комментариях).

Вы вызываете tell Unity, какой конструктор использовать с использованием InjectionConstructor.

Ниже приводится указание использовать конструктор без параметров.

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

или вы могли бы также сказать ему, чтобы использовать один с типом, а также.

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

Это приведет к принудительному использованию Unity конструктором, который вы хотите.