I separated controllers and views on two project on last mvc version 5.2.6
We have many client project with same controller but sometime it need to override controllers.
I would do something like : Default controller in my library project but if we found controller in the main project take this one, kind of order for controllers.
But when I do :
ControllerBuilder.Current.DefaultNamespaces.Add("MainProject.Controllers");
ControllerBuilder.Current.DefaultNamespaces.Add("Library.Controllers");
I get an error controller is ambiguous
The Idea is to have a common controllers for all client website. Client website will contains only views but de need to override some controllers for specific client developments.
In my example I have two similar controllers. One in the Core namespace and one in Client:
namespace CustomControllerFactory.Core.Controllers
{
public class DemoController : Controller
{
public ActionResult Index()
{
ViewBag.CalledFrom = "Core";
return View();
}
}
}
namespace CustomControllerFactory.Client.Controllers
{
public class DemoController : Controller
{
public ActionResult Index()
{
ViewBag.CalledFrom = "Client";
return View();
}
}
}
For this I have created a custom controller factory:
public class CustomControllerFactory : IControllerFactory
{
public IController CreateController(RequestContext requestContext, string controllerName)
{
var ns = MethodBase.GetCurrentMethod().DeclaringType.Namespace;
var coreNs = $"{ns}.Core.Controllers";
var clientNs = $"{ns}.Client.Controllers";
//find out if core or client exists: https://stackoverflow.com/questions/8499593/c-sharp-how-to-check-if-namespace-class-or-method-exists-in-c
var coreControllers = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where type.Namespace == coreNs
select type);
var clientControllers = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where type.Namespace == clientNs
select type);
Type controllerFullType = null;
if (coreControllers.Any(x => x.Name == $"{controllerName}Controller"))
{
controllerFullType = Type.GetType($"{ns}.Core.Controllers.{controllerName}Controller");
}
else if (clientControllers.Any(x => x.Name == $"{controllerName}Controller"))
{
controllerFullType = Type.GetType($"{ns}.Client.Controllers.{controllerName}Controller");
}
else
{
throw new ApplicationException("no valid controller found");
}
IController controller = Activator.CreateInstance(controllerFullType) as Controller;
return controller;
}
public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
{
return SessionStateBehavior.Default;
}
public void ReleaseController(IController controller)
{
(controller as IDisposable)?.Dispose();
}
}
This does the following:
Then you have to register your factory in your global.asax:
ControllerBuilder.Current.SetControllerFactory(typeof(CustomControllerFactory));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.