Reputation: 12817
I'm reading through the source code for ASP.NET MVC3, and I came across the following inside of the code for ControllerBase:
public interface IController
{
void Excecute(RequestContext requestContext);
}
public abstract class ControllerBase : IController
{
protected virtual void Execute(RequestContext requestContext)
{
if (requestContext == null)
{
throw new ArgumentNullException("requestContext");
}
if (requestContext.HttpContext == null)
{
throw new ArgumentException(MvcResources.ControllerBase_CannotExecuteWithNullHttpContext, "requestContext");
}
VerifyExecuteCalledOnce();
Initialize(requestContext);
using (ScopeStorage.CreateTransientScope())
{
ExecuteCore();
}
}
void IController.Execute(RequestContext requestContext)
{
Execute(requestContext);
}
}
ControllerBase provides an implementation of Execute
, but then it has something that provides a definition for.. IController.Execute
?
Why is this done, and what does it achieve? It seems like it serves no purpose.
Upvotes: 9
Views: 247
Reputation: 16900
This code makes it possible for you to override the Execute method.
Remember that a normally implemented interface method is public (and not virtual or abstract), so you can't override it in derived classes and creating a new Execute method wouldn't be accessible through the IController
interface by default (without this interface to protected virtual technique). By creating a protected virtual method (which you call from the explicitly implemented interface method) allows derived classes to override the Execute method without breaking the interface implementation.
I found an excellent article about this here: C# Overriding Interface Methods in Subclasses
Upvotes: 6
Reputation: 1876
At first glance this design pattern would seem to serve no purpose. It does, however, provide the opportunity for the ControllerBase
class to later make non-breaking changes its implementation of the IController
interface. The changes would be guaranteed to run, as it does not rely on the inherited classes calling base.Execute()
. Perhaps this could be used to manage contexts or security in the future?
Maybe the developer just likes to keep a logical separation of the interface with overridable implementation.
Upvotes: 1
Reputation: 13907
According to MSDN Documentation, one purpose of explicit interface member implementation is: "Because explicit interface member implementations are not accessible through class or struct instances, they allow interface implementations to be excluded from the public interface of a class or struct. This is particularly useful when a class or struct implements an internal interface that is of no interest to a consumer of that class or struct."
If my interpretation of the above is correct, a variable with type ControllerBase
cannot be used to call Execute
because it is protected. The type of the variable has to be IController
. I am not sure if this is the intent of the construct, but it feels like this is the reason.
In the relevant tests, they explicitly cast the ControllerBase
variables to IController
before calling Execute
.
Upvotes: 2