2010-09-04 5 views
4

Je suis en train de construire une classe comme si ...Remplacer une méthode virtuelle interne protégée C#

public class IoCControllerFactory : DefaultControllerFactory 
    {   
     protected override IController GetControllerInstance(RequestContext request_context, Type controller_type) 
     { 
      // Attempt to resolve controller type. 
      IController resolvedController = null; 
      if (controller_type != null) 
      { 

       if (!typeof(IController).IsAssignableFrom(controller_type)) 
       { 
        throw new ArgumentException(string.Format("Type requested is not a controller: {0}", controller_type.Name), "controller_type"); 
       } 

       resolvedController = _container.Resolve(controller_type) as IController; 
      } 

      // Throw page not found if controller does not exist. 
      if (resolvedController == null) 
      { 
       throw new HttpException((int)HttpStatusCode.NotFound, "The requested page was not found."); 
      } 

      return resolvedController; 
     } 

    } 

La méthode tente de passer outre une méthode virtuelle interne qui a la signature followign (de l'assemblage .net ... je ne peux pas modifier ce)

protected internal virtual IController GetControllerInstance(
    RequestContext requestContext, 
    Type controllerType 
) 

Quand je tente de compiler j'obtiens ce qui suit ...

'XXX.Web.Mvc.IoCControllerFactory.GetControllerInstance(System.Web.Routing.RequestContext, System.Type)': no suitable method found to override 

Tout le monde sur le web semble être capable de faire ça très bien, y a-t-il quelque chose d'évident qui me manque?

+0

Supprimer 'internal' de la signature de' GetControllerInstance'? Est-ce que ça marche? –

+0

@Jason, cette méthode est définie dans l'assemblage ASP.NET MVC, vous ne pouvez pas le modifier –

+0

voici une autre clé .... Si je déplace la classe à un autre assemblage, il fonctionne très bien. SI je l'enlève de mon assemblage d'origine, l'assemblage se construit !! Cela me bouscule vraiment. –

Répondre

1

Je viens de rencontrer ce problème; Si la solution choisie n'était pas réellement votre problème, alors le type RequestContext est envoyé depuis l'assembly System.Web.Routing vers System.Web. La solution consiste à la fois à référencer System.Web et System.Web.Routing.

+0

cool merci de partager cela. –

2

Nouveau (possible) Réponse

Je suis en mesure de reproduire ce problème si j'ai défini un type avec le même nom que l'un de l'ensemble « System.Web.Mvc.dll » dans ma propre bibliothèque. Serait-ce votre problème? Voir le code ci-dessous:

using System; 
using System.Web.Mvc; 
using System.Web.Routing; 

namespace SystemWebMvcTest 
{ 
    // See here: I've declared a type with the same name as a type 
    // from the System.Web.Mvc namespace in System.Web.Mvc.dll. 
    public interface IController 
    { 
    } 

    public class IoCControllerFactory : DefaultControllerFactory 
    { 
     // Now this method signature, since it does not include the fullly 
     // qualified name of its return type, is actually defined to return 
     // an instance of the IController interface defined in THIS assembly, 
     // rather than the System.Web.Mcv.IController interface. 
     protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) 
     { 
      return null; 
     } 
    } 
} 

La même erreur doit se produire si vous avez un conflit de nom avec l'un des types pertinents: DefaultControllerFactory, IController, RequestContext ou Type.


Old réponse

La méthode originale est protected internal, ce qui signifie qu'il est possible d'accéder par tout type au sein du même ensemble ainsi que tout type dérivé; mais vous essayez de la remplacer par une méthode qui est protected, qui supprime l'accès à tous les types non dérivés, même dans le même ensemble que le type de base.

Ce n'est pas si différent d'essayer de remplacer un membre public avec un private. Tu ne peux pas faire ça. vous auriez à le déclarer dérivé new au lieu de override (ce qui est une idée assez mauvaise, presque tout le temps).

Mark votre méthode IoCControllerFactory.GetControllerInstanceprotected internal et vous devriez être bon.

MISE À JOUR: En fait, comme Thomas l'a souligné dans un commentaire, cela dépend totalement si votre type dérivé est dans le même assemblage que le type de base ou non. Si pas, déclarant le membre dérivé protected internal aurait aucun sens. Si vous êtes dans un assemblage différent, je ne sais pas pourquoi déclarer le membre protected provoque une erreur car c'est exactement ce que vous êtes censé faire.

MISE À JOUR 2: Il semble que dans le code que vous avez posté, votre base et types dérivés sont dans le même ensemble. C'est pourquoi la méthode IoCControllerFactory.GetControllerInstance doit être marquée protected internal, pour correspondre à l'accessibilité de son type de base. Si vous étiez dans un ensemble séparé, internal aurait tort, car il ouvrirait l'accès à une nouvelle série de types (ceux dans ce nouvel ensemble).Si vous avez vu des exemples de code en ligne où un type dans un assembly a hérité un membre protected internal d'un type de base dans un autre, cela explique pourquoi le membre dérivé était seulement protected - pour que l'accessibilité reste la même.

MISE À JOUR 3: Peu importe! Apparemment, le type de base est dans un assembly .NET, ce qui est clairement différent de l'assemblage dans lequel se trouve votre type dérivé. Sur cette base, la signature de votre méthode devrait en fait être compilée telle quelle, pour autant que je sache. Une question dans mon esprit est si tous ces noms - DefaultControllerFactory, IController, RequestContext, etc. - ne sont pas également présents dans votre assemblée. Si vous avez un conflit de noms, cela pourrait être une explication possible. Sinon, je ne comprends pas l'erreur du compilateur que vous obtenez.

+0

Non, les méthodes 'protected internal' devraient être remplacées par' protected'. Si vous essayez de les remplacer par "protected internal", vous obtenez une erreur de compilation. Voir [cette réponse] (http://stackoverflow.com/questions/2375792/overriding-protected-internal-with-protected/2375947#2375947). 'protected internal' permettrait l'accès à cette méthode à toutes les classes de votre assembly, ce qui élargit incorrectement son accessibilité –

+0

bien, c'est ma première pensée, mais si vous google ce scenerio particulier, avec n'importe quel cadre MVC IoC, ils sont 100% capables pour accomplir ceci comme décrit. Quand je le déplace vers un autre assemblage et que je le construis, ça marche aussi bien. –

+0

@Thomas, @wcpro: Voir ma mise à jour. Je pense que cela répond à ce que vous dites tous les deux. –

Questions connexes