2010-12-28 14 views
2

Edit: Das festgelegt ist - Siehe Lösung unterASP.NET MVC2 Fehler: Kein parameterlosen Konstruktor für dieses Objekt definiert

Lösung: Zuerst hatte ich falsch meinen Knoten in /shared/web.config definiert anstelle der web.config im Stammverzeichnis des WebUI-Projekts. Ich hatte auch meine Verbindungszeichenfolge in web.config nicht korrekt definiert. Ich habe die richtigen web.config Abschnitte unten eingefügt:

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

Ich musste auch die Methode Körper WindsorControllerFactory.cs (IoC Container) einstellen null für ungültige Anfragen zurück wie so:

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

Ende der Lösung

Ich folge dem Buch Pro ASP.NET MVC2 von Sanderson. Ich habe den IoC-Container implementiert und die web.config begradigt. Wenn ich versuche, meine Anwendung auszuführen, erhalte ich den Fehler "Kein parametrischer Konstruktor für dieses Objekt definiert"

Nach einigem Suchen fand ich dieses genaue Problem auf SO here. Die Lösung besteht darin, den Konstruktor ohne Parameter zu erstellen, aber ich habe ein Problem damit. Ich habe unter

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

Oberhalb des öffentlichen Products den Code aus ProductsController.cs eingefügt, die Parameter habe ich tun versucht:

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

Ich bin unklar, was genau nach dem „neuen gehen muss ". IProductsRepository scheint nicht zu funktionieren und tut auch nicht, was ich geschrieben habe. Ich habe den Stack-Trace eingefügt:

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 

Jede Hilfe würde sehr geschätzt werden.

Edit: Veröffentlichung WindsorControllerFactory.cs Code:

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

    } 
} 

Edit2: Einschlägige Web.config Knoten:

<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> 
+0

möglich Duplikat [ASP tun können.NET MVC: Kein parameterloser Konstruktor für dieses Objekt definiert] (http://stackoverflow.com/questions/1355464/asp-net-mvc-no-parameterless-constructor-defined-for-this-object) –

Antwort

4

Sie benötigen eine eigene Controller Fabrik, um Ihre DI Rahmen verkabeln konfigurieren innerhalb Application_Start Methode in global.asax. So zum Beispiel, wenn Sie die Einheit als DI Framework verwenden Sie könnten:

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

Check out this blog post für weitere Informationen.

+0

Ich habe diesen Eintrag bereits in meiner Global.asax-Datei, um Castle Windsor zu verwenden. ControllerBuilder.Current.SetControllerFactory (neue WindsorControllerFactory()); –

+0

@Caley Woods, könnten Sie Ihren Code zeigen, der die Controller und ihre Abhängigkeiten mit Castle Windsor registriert? –

+0

Ich habe meinen ursprünglichen Post bearbeitet, der ist unten. –

0

können Sie nutzen Setter basierend Injektion

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

hier, können Sie die MyRepository manuell einstellen vornehmen müssen.

aber am besten wäre, wenn Sie Ihr Repository in einen Container registrieren und beliving, dass Sie Unity Framework verwenden, so dass Sie es von IUnityContainer.RegisterType() -Methode

Verwandte Themen