public virtual void Initialize(Type controllerType)
{
ConstructorInfo constructor = controllerType.GetConstructor(Type.EmptyTypes);
if (constructor != null)
{
DynamicMethod inv = new DynamicMethod("CreateController", typeof(object), Type.EmptyTypes);
ILGenerator invIL = inv.GetILGenerator();
invIL.Emit(OpCodes.Newobj, constructor);
invIL.Emit(OpCodes.Ret);
_controllerCreator = (Func<object>)inv.CreateDelegate(typeof(Func<object>));
}
//throw new BindingException("Controller " + controllerType.Name + " doesn't contain a public no-arguments constructor.");
/*
_controllerCreator = () =>
{
try
{
return System.Activator.CreateInstance(controllerType);
}
catch (TargetInvocationException ex)
{
throw ex.InnerException;
}
};*/
PropertyHandler[] properties;
List<PropertyHandler> props = new List<PropertyHandler>();
foreach (PropertyInfo p in controllerType.GetProperties())
{
object[] propAttributes = p.GetCustomAttributes(typeof(IPropertyBinding), false);
for (int i = 0; i < propAttributes.Length; i++)
{
IPropertyBinding b = (IPropertyBinding)propAttributes[i];
b.Initialize(p);
props.Add(new PropertyHandler { Binding = b, Property = p });
}
}
if (props.Count > 0) properties = props.ToArray();
else properties = null;
IExtension[] controllerExtensions;
object[] exts = controllerType.GetCustomAttributes(typeof(IExtension), true);
if (exts.Length > 0)
{
controllerExtensions = new IExtension[exts.Length];
for (int i = 0; i < exts.Length; i++)
{
IExtension ext = (IExtension)exts[i];
ext.Initialize(controllerType);
controllerExtensions[i] = ext;
}
}
else
controllerExtensions = null;
List<ActionHandler> handlers = new List<ActionHandler>();
foreach (MethodInfo m in controllerType.GetMethods(BindingFlags.Public | BindingFlags.Instance))
{
object[] actionAttributes = m.GetCustomAttributes(typeof(IActionBinding), false);
if (actionAttributes.Length > 0)
{
IExtension[] actionExtensions;
exts = m.GetCustomAttributes(typeof(IExtension), true);
if (exts.Length > 0)
{
actionExtensions = new IExtension[exts.Length];
for (int i = 0; i < exts.Length; i++)
{
IExtension ext = (IExtension)exts[i];
ext.Initialize(m);
actionExtensions[i] = ext;
}
}
else
actionExtensions = null;
IActionBinding[] bs = new IActionBinding[actionAttributes.Length];
for (int i = 0; i < actionAttributes.Length; i++)
{
IActionBinding a = bs[i] = (IActionBinding)actionAttributes[i];
a.Initialize(m);
ParameterInfo[] ps = m.GetParameters();
ParameterInfo sl = ps.Length > 1 ? ps[ps.Length - 2] : null;
ParameterInfo l = ps.Length > 1 ? ps[ps.Length - 1] : null;
bool isAsync = m.ReturnType == typeof(IAsyncResult) && sl != null &&
!sl.ParameterType.IsByRef && sl.ParameterType == typeof(AsyncCallback) &&
!l.ParameterType.IsByRef && l.ParameterType == typeof(object);
bool isParentAction = !isAsync && typeof(IController).IsAssignableFrom(m.ReturnType) || m.ReturnType.GetCustomAttributes(typeof(IControllerBinding), false).Length > 0;
ActionHandler handler = isAsync ? new AsyncActionHandler() : (isParentAction ? new ParentActionHandler() : new ActionHandler());
handler.Action = m;
handler.Binding = a;
handler.ControllerExtensions = controllerExtensions;
handler.ActionExtensions = actionExtensions;
handler.Properties = properties;
if (isAsync)
{
string name = m.Name.StartsWith("Begin", StringComparison.InvariantCultureIgnoreCase) ? m.Name.Substring(5) : m.Name;
MethodInfo em = controllerType.GetMethod("End" + name, new Type[] { typeof(IAsyncResult) });
if (em == null) controllerType.GetMethod(name, new Type[] { typeof(IAsyncResult) });
if (em == null) throw new BindingException(String.Format("Beginning of asynchronous method '{0}' is missing the expected '{1}' end method.", m.Name, "End" + name));
((AsyncActionHandler)handler).EndAction = em;
}
handlers.Add(handler);
}
}
}
if (handlers.Count > 0)
_handlers = handlers.ToArray();
}