开发者

Override a protected internal virtual method in c#

I am trying to build a class like so...

    public class IoCControllerFactory : DefaultControllerFactory
    {           
        protected override IController GetControllerInstance(RequestContext request_context, Type controller_type)
        {
            // Attempt to resolve controller type.
            IContr开发者_C百科oller 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;
        }

    }

The method is trying to override an internal virtual method that has the followign signature (from .net assembly... i cant modify this)

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

When i try to compile i get the following...

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

Everybody on the web seems to be able to do this just fine, is there something obvious that I am missing?


New (Possible) Answer

I am able to duplicate this issue if I've defined a type with the same name as one from the "System.Web.Mvc.dll" assembly in my own library. Could this be your problem? See the code below:

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

The same error should occur if you have a naming conflict with any of the relevant types: DefaultControllerFactory, IController, RequestContext, or Type.


Old Answer

The original method is protected internal, which means that it can be accessed by any type within the same assembly as well as any derived type; but you are trying to override it with a method that is protected, which removes access to all non-derived types, even in the same assembly as the base type.

This isn't really so different from trying to override a public member with a private one. You can't do that; you'd have to declare the derived member new instead of override (which is a pretty bad idea, almost all the time).

Mark your IoCControllerFactory.GetControllerInstance method protected internal and you should be good.

UPDATE: Actually, as Thomas pointed out in a comment, this totally depends on whether your derived type is in the same assembly as the base type or not. If not, then declaring the derived member protected internal would make no sense. If you're in a different assembly, then I'm not sure why declaring the member protected is causing an error as this is exactly what you're supposed to do.

UPDATE 2: It sounds like in the code you've posted, your base and derived types are in the same assembly. This is why the IoCControllerFactory.GetControllerInstance method must be marked protected internal, to match the accessibility of its base type. If you were in a separate assembly, internal would be wrong, as it would open up the accessibility to a whole new set of types (those within this new assembly). If you've seen code examples online where a type in one assembly inherited a protected internal member from a base type in another, this explains why the derived member was only protected -- to keep accessibility the same.

UPDATE 3: Never mind! Apparently the base type is in a .NET assembly, which is clearly different from whatever assembly your derived type is in. Based on this, your method signature should actually compile as-is, as far as I can tell. One question in my mind is whether all of these names -- DefaultControllerFactory, IController, RequestContext, etc. -- are not also present in your assembly. If you have a naming conflict, this could be one possible explanation. Otherwise, I fail to understand the compiler error you're getting.


I've just came across this problem; If the chosen solution wasn't really your problem, then is that the RequestContext type is forwared from the System.Web.Routing assembly into the System.Web one. The solution is to both reference System.Web and System.Web.Routing.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜