Imagine an MVC project without any controller in that solution. I have same thing and want to create controller at runtime by using a DefaultControllerFactory then register it in my Global.asax by Autofac.
Here I have a sample controller factory which has CreateController method:
internal class CControllerFactory : DefaultControllerFactory
{
private readonly Dictionary<string, Func<RequestContext, IController>> _controllerMap;
public CControllerFactory()
{
List<IController> lstControllers = DependencyResolver.Current.GetServices<IController>().ToList();
_controllerMap = new Dictionary<string, Func<RequestContext, IController>>();
foreach (Controller contr in lstControllers)
{
string ctrName = contr.ControllerContext.RouteData.Values["Controller"].ToString();
_controllerMap.Add(ctrName, c => contr);
}
}
public override IController CreateController(RequestContext requestContext, string controllerName)
{
if (_controllerMap.ContainsKey(controllerName))
{
return _controllerMap[controllerName](requestContext);
}
else
throw new KeyNotFoundException(controllerName);
}
}
As you see above, this line: List<IController> lstControllers = DependencyResolver.Current.GetServices<IController>().ToList(); will get the list of controllers which use IController service. But in my case there is no controller exist in the solution. I want to create a new controller at run time and add it in my _controllerMap.
So I changed code to this:
internal class CControllerFactory : DefaultControllerFactory
{
private readonly Dictionary<string, Func<RequestContext, IController>> _controllerMap;
public CControllerFactory()
{
// *Don't need this*
// List<IController> lstControllers = DependencyResolver.Current.GetServices<IController>().ToList();
_controllerMap = new Dictionary<string, Func<RequestContext, IController>>();
// *Don't need this Foreach*
// foreach (Controller contr in lstControllers)
// {
string ctrName = "Home";
// But what about contr in this line?!?!:
_controllerMap.Add(ctrName, c => contr);
// }
}
public override IController CreateController(RequestContext requestContext, string controllerName)
{
if (_controllerMap.ContainsKey(controllerName))
{
return _controllerMap[controllerName](requestContext);
}
else
throw new KeyNotFoundException(controllerName);
}
}
So what about contr in specified line? This argument must to be type of Func<RequestContext,IController>. How can I create it functionally by C# code?