|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Web;
using System.Web.UI;
namespace Demo.Web.Mvvm
{
internal class PageControllerBuilder
{
internal static void CreateController(Control target)
{
if (target == null) throw new ArgumentNullException("in-prarm target is null");
foreach (var prop in ReflectionCache.GetProperties(target.GetType(), typeof(CreateAttribute)))
{
var attributes = prop.GetCustomAttributes(typeof(CreateAttribute), false);
if (attributes.Length > 0 && prop.GetValue(target, null) == null)
{
CreateAttribute attribute = attributes[0] as CreateAttribute;
object instance = CreateInstance(prop.PropertyType, attribute);
prop.SetValue(target, instance, null);
SubscribeEvents(target, instance, prop.Name);
}
}
}
private static object CreateInstance(Type type, CreateAttribute attribute)
{
object instance;
string key = string.IsNullOrEmpty(attribute.Id) ? type.FullName : attribute.Id;
switch (attribute.Scope)
{
case CreateScope.Application:
instance = HttpContext.Current.Application[key];
if (instance == null)
{
instance = Activator.CreateInstance(type);
HttpContext.Current.Application[key] = instance;
}
break;
case CreateScope.Session:
instance = HttpContext.Current.Session[key];
if (instance == null)
{
instance = Activator.CreateInstance(type);
HttpContext.Current.Session[key] = instance;
}
break;
case CreateScope.Request:
instance = HttpContext.Current.Items[key];
if (instance == null)
{
instance = Activator.CreateInstance(type);
HttpContext.Current.Items[key] = instance;
}
break;
default: //CreateScope.Control:
instance = Activator.CreateInstance(type);
break;
}
return instance;
}
internal static void InjectController(Control target)
{
if (target == null) throw new ArgumentNullException("in-prarm target is null");
foreach (var prop in ReflectionCache.GetProperties(target.GetType(), typeof(InjectAttribute)))
{
var attributes = prop.GetCustomAttributes(typeof(InjectAttribute), false);
if (attributes.Length > 0 && prop.GetValue(target, null) == null)
{
InjectAttribute attribute = attributes[0] as InjectAttribute;
object instance = InjectInstance(target, prop.PropertyType, attribute);
prop.SetValue(target, instance, null);
SubscribeEvents(target, instance, prop.Name);
}
}
}
private static object InjectInstance(Control target, Type type, InjectAttribute attribute)
{
object instance = null;
switch (attribute.Scope)
{
case InjectScope.Application:
if (string.IsNullOrEmpty(attribute.Id))
{
for (int i = 0; i < HttpContext.Current.Application.Count; i++)
{
object obj = HttpContext.Current.Application[i];
Type objtype = obj.GetType();
if (objtype == type || (objtype.GetInterface(type.FullName) != null))
{
instance = HttpContext.Current.Application[i];
break;
}
}
}
else
{
object obj = HttpContext.Current.Application[attribute.Id];
if (obj != null)
{
Type objtype = obj.GetType();
if (objtype == type || (objtype.GetInterface(type.FullName) != null))
{
instance = HttpContext.Current.Application[attribute.Id];
}
}
}
break;
case InjectScope.Session:
if (string.IsNullOrEmpty(attribute.Id))
{
for (int i = 0; i < HttpContext.Current.Session.Count; i++)
{
object obj = HttpContext.Current.Session[i];
Type objtype = obj.GetType();
if (objtype == type || (objtype.GetInterface(type.FullName) != null))
{
instance = HttpContext.Current.Session[i];
break;
}
}
}
else
{
object obj = HttpContext.Current.Session[attribute.Id];
if (obj != null)
{
Type objtype = obj.GetType();
if (objtype == type || (objtype.GetInterface(type.FullName) != null))
{
instance = HttpContext.Current.Session[attribute.Id];
}
}
}
break;
case InjectScope.Page:
foreach (PropertyInfo prop in ReflectionCache.GetProperties(target.Page.GetType(), typeof(CreateAttribute)))
{
if (prop.PropertyType == type || (prop.PropertyType.GetInterface(type.FullName) != null))
{
instance = prop.GetValue(target.Page, null);
break;
}
}
break;
default: // InjectScope.Parent:
Control control = target;
while (control != null)
{
control = control.Parent;
if ((control is UserControl) || (control is Page))
{
foreach (PropertyInfo prop in ReflectionCache.GetProperties(control.GetType(), typeof(CreateAttribute)))
{
if (prop.PropertyType == type || (prop.PropertyType.GetInterface(type.FullName) != null))
{
instance = prop.GetValue(control, null);
control = null;
break;
}
}
}
}
break;
}
return instance;
}
internal static void CreateControllerInChildren(Control parent)
{
if (parent.Controls.Count > 0)
{
foreach (Control control in parent.Controls)
{
if (control is UserControl)
{
CreateController(control);
}
if (control.Controls.Count > 0) CreateControllerInChildren(control);
}
}
}
internal static void InjectControllerInChildren(Control parent)
{
if (parent.Controls.Count > 0)
{
foreach (Control control in parent.Controls)
{
if (control is UserControl)
{
InjectController(control);
}
if (control.Controls.Count > 0) InjectControllerInChildren(control);
}
}
}
public static void BuildController(Page page)
{
if (page == null) throw new ArgumentNullException("in-prarm page is null");
CreateController(page);
CreateControllerInChildren(page);
InjectController(page);
InjectControllerInChildren(page);
}
internal static void UnloadController(Page page)
{
if (page == null) throw new ArgumentNullException("in-prarm page is null");
UnSubscribeEvents(page);
}
private static void SubscribeEvents(Control target, object controller, string propertyName)
{
if (target == null || controller == null) return;
foreach (MethodInfo method in ReflectionCache.GetMethods(target.GetType().BaseType, typeof(EventSubscriptionAttribute)))
{
var attributes = method.GetCustomAttributes(typeof(EventSubscriptionAttribute), false);
foreach (object attribute in attributes)
{
string eventName = ((EventSubscriptionAttribute)attribute).EventName ?? method.Name;
EventInfo publishedEvent = controller.GetType().GetEvent(eventName,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
if (publishedEvent != null && IsNotStatic(publishedEvent) && IsValidHandler(publishedEvent))
{
Delegate handler = Delegate.CreateDelegate(publishedEvent.EventHandlerType, target, method);
publishedEvent.AddEventHandler(controller, handler);
EventLinks.Add(new EventLink
{
EventInfo = publishedEvent,
Target = controller,
Handler = handler,
});
}
}
}
}
private static bool IsValidHandler(EventInfo publishedEvent)
{
return !publishedEvent.GetAddMethod().IsStatic && !publishedEvent.GetRemoveMethod().IsStatic;
}
private static bool IsNotStatic(EventInfo publishedEvent)
{
return typeof(EventHandler).IsAssignableFrom(publishedEvent.EventHandlerType) ||
(publishedEvent.EventHandlerType.IsGenericType &&
typeof(EventHandler<>).IsAssignableFrom(publishedEvent.EventHandlerType.GetGenericTypeDefinition()));
}
private static void UnSubscribeEvents(Control parent)
{
foreach (EventLink link in EventLinks)
{
link.EventInfo.RemoveEventHandler(link.Target, link.Handler);
}
}
private const string key = "_events_";
private static List<EventLink> EventLinks
{
get
{
var events = HttpContext.Current.Items[key] as List<EventLink>;
if (events == null)
{
events = new List<EventLink>();
HttpContext.Current.Items[key] = events;
}
return events;
}
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.