ASP.NET MVC2 Ошибка: для этого объекта не определен конструктор без параметров - PullRequest
2 голосов
/ 28 декабря 2010

Редактировать: это исправлено - см. Решение ниже

Решение : Сначала я неправильно определил свой узел в /shared/web.config вместоweb.config в корне проекта WebUI.Я также неправильно определил строку подключения в web.config.Я вставил соответствующие разделы web.config ниже:

<configuration>
  <configSections>
    <section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor"/>
  <!--more sectiongroup and sections redacted for brevity -->
  </configSections>
  <castle>
      <components>
          <component id="ProdsRepository" service="DomainModel.Abstract.IProductsRepository, DomainModel" type="DomainModel.Concrete.SqlProductsRepository, DomainModel">
              <parameters>
                  <connectionString>Data Source=.\SQLExpress;Initial Catalog=SportsStore; Integrated Security=SSPI</connectionString>
              </parameters>
          </component>
      </components>
  </castle>

Мне также пришлось настроить тело метода WindsorControllerFactory.cs (IoC Container), чтобы оно возвращало ноль для недопустимых запросов, например так:

protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
    if (controllerType == null)
        return null;
    else
    return (IController)container.Resolve(controllerType);
}

Конец решения

Я слежу за книгой Pro ASP.NET MVC2 Сандерсона.Я реализовал контейнер IoC и выправил web.config.Когда я пытаюсь запустить свое приложение, я получаю сообщение об ошибке «Для этого объекта не определен конструктор без параметров»

После некоторых поисков я нашел именно эту проблему на SO здесь .Решение состоит в том, чтобы создать конструктор без параметров, но у меня возникла проблема с этим.Я вставил код из ProductsController.cs ниже

namespace WebUI.Controllers
    {
        public class ProductsController : Controller
           {
               private IProductsRepository productsRepository;
               public ProductsController(IProductsRepository productsRepository)
               {
                   this.productsRepository = productsRepository;
               }

        public ViewResult List()
        {
            return View(productsRepository.Products.ToList());
        }
    }
}

Над общедоступным ProductsController с параметрами, которые я пытался сделать:

public ProductsRepository() : this(new productsRepository())
{
}

Мне неясно, что именно нужно сделатьпосле "нового".IProductsRepository, похоже, не работает и не выполняет то, что я написал.Я вставил трассировку стека ниже:

Stack Trace: 


[MissingMethodException: No parameterless constructor defined for this object.]
   System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck) +0
   System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean fillCache) +86
   System.RuntimeType.CreateInstanceImpl(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean fillCache) +230
   System.Activator.CreateInstance(Type type, Boolean nonPublic) +67
   System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +80

[InvalidOperationException: An error occurred when trying to create a controller of type 'WebUI.Controllers.ProductsController'. Make sure that the controller has a parameterless public constructor.]
   System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +190
   System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +68
   System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +118
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +46
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +63
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +13
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8682818
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

Любая помощь будет принята с благодарностью.

Редактировать: Отправка кода WindsorControllerFactory.cs:

namespace WebUI
{
    public class WindsorControllerFactory : DefaultControllerFactory
    {
        WindsorContainer container;

        // The contructor:
        // 1. Sets up a new IoC container
        // 2. Registers all components specified in web.config
        // 3. Registers all controller types as components
        public WindsorControllerFactory()
        {
            // Instantiate a container, taking config from web.config
            container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));

            // Also register all the controller types as transient
            var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
                                  where typeof(IController).IsAssignableFrom(t)
                                  select t;
            foreach (Type t in controllerTypes)
                container.AddComponentLifeStyle(t.FullName, t, Castle.Core.LifestyleType.Transient);
        }

        // Constructs the controller instance needed to service each request
        protected override IController  GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            return (IController)container.Resolve(controllerType);
        }

    }
}

Редактировать2: УместноУзлы Web.config:

<configSections>
    <section name="castle"
             type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler,
                 Castle.Windsor" />
  </configSections>
  <castle>
    <components>
      <component id="ProdsRepository"
                 service="DomainModel.Abstract.IproductsRepository, DomainModel"
                 type="DomainModel.Concrete.SqlProductsRepository, DomainModel"></component>
      <parameters>
      </parameters>
    </components>
  </castle>

Ответы [ 2 ]

4 голосов
/ 28 декабря 2010

Вам необходимо настроить фабрику пользовательских контроллеров, чтобы подключить вашу DI-структуру внутри метода Application_Start в global.asax.Например, если вы используете Unity в качестве DI-фреймворка, вы можете:

ControllerBuilder.Current.SetControllerFactory(
    typeof(UnityControllerFactory)
);

Проверить эту запись в блоге для получения дополнительной информации.

0 голосов
/ 28 декабря 2010

вы можете использовать инъекцию на основе установки

    public class ProductsController : Controller 

{   
    private IProductsRepository productsRepository; 

    public ProductsController()
    {

    } 
    public ViewResult List() 
    {
        return View(productsRepository.Products.ToList());
    }

    public IProductsRepository MyRepository
    {
        get
        {
            return productsRepository;
        }

        set
        {
            productsRepository = value;
        }
    }
}

здесь, вам нужно вручную установить MyRepository.

, но лучше всего, если вы зарегистрируете свой репозиторий в контейнереполагая, что вы используете платформу Unity, вы можете сделать это с помощью метода IUnityContainer.RegisterType ()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...