public IConstructorBuilder DefineConstructor(MethodAttributes attributes, IType[] parameters) { var builder = new AsmConstructorBuilder(this, attributes, parameters); TypeConstructors.Add(builder); return(builder); }
static void Main(string[] args) { //RttiWithIs.Start(); //RttiWithAs.Start(); //SimpleTypeofExample.Start(); //ReflectionDemo.Start(); //CallingMethodsUsingReflection.Start(); TypeConstructors.Start(); Console.ReadKey(); }
private IProductType Transform(IUnitOfWork uow, ProductTypeEntity typeEntity, bool full, IDictionary <long, IProductType> loadedProducts = null, IProductPartLink parentLink = null) { // Build cache if this wasn't done before if (loadedProducts == null) { loadedProducts = new Dictionary <long, IProductType>(); } // Take converted product from dictionary if we already transformed it if (loadedProducts.ContainsKey(typeEntity.Id)) { return(loadedProducts[typeEntity.Id]); } // Strategy to load product and its parts var strategy = TypeStrategies[typeEntity.TypeName]; // Load product var product = TypeConstructors[typeEntity.TypeName](); product.Id = typeEntity.Id; product.Name = typeEntity.Name; product.State = (ProductState)typeEntity.CurrentVersion.State; product.Identity = new ProductIdentity(typeEntity.Identifier, typeEntity.Revision); strategy.LoadType(typeEntity.CurrentVersion, product); // Don't load parts and parent for partial view if (full) { LoadParts(uow, typeEntity, product, loadedProducts); } // Assign instance to dictionary of loaded products loadedProducts[typeEntity.Id] = product; return(product); }
public FormDefinition GetDefinition(string xml, bool freeze) { var document = XDocument.Parse(xml); if (document.Root == null) { throw new InvalidOperationException("Invalid XML document."); } void AddMetadata(IDictionary <string, string> dict, XElement xelement) { const int stroffset = 5; // "meta-".Length foreach (var attr in xelement.Attributes()) { if (attr.Name.LocalName.StartsWith("meta-", StringComparison.OrdinalIgnoreCase)) { dict[attr.Name.LocalName.Substring(stroffset)] = attr.Value; } } } FormElement WithMetadata(FormElement element, XElement xelement) { AddMetadata(element.Metadata, xelement); return(element); } ILayout Terminal(XElement element) { var elementName = element.Name.LocalName.ToLower(); FormElement formElement; switch (elementName) { case "layout": return(Layout(element)); case "input": case "textarea": case "toggle": case "password": { var typeName = element.TryGetAttribute("type") ?? "string"; var attributes = new List <Attribute>(); Type propertyType; if (elementName == "input" && TypeConstructors.TryGetValue(typeName, out var constructor)) { var data = constructor(new XmlConstructionContext(element)); propertyType = data.PropertyType; attributes.AddRange(data.CustomAttributes); } else if (!TypeNames.TryGetValue(typeName, out propertyType)) { throw new InvalidOperationException($"Type '{typeName}' not found."); } var fieldName = element.TryGetAttribute("name"); attributes.Add(Utilities.GetFieldAttributeFromElement(element)); attributes.Add(Utilities.GetBindingAttributeFromElement(element)); switch (elementName) { case "textarea": attributes.Add(new MultiLineAttribute()); propertyType = typeof(string); break; case "toggle": attributes.Add(new ToggleAttribute()); propertyType = typeof(bool); break; case "password": attributes.Add(new PasswordAttribute()); propertyType = typeof(string); break; } attributes.AddRange(Utilities.GetValidatorsFromElement(element)); var property = new DynamicProperty(fieldName, propertyType, attributes.ToArray()); var deserializer = TryGetDeserializer(propertyType); formElement = Build(property, deserializer); if (formElement != null) { foreach (var initializer in FieldInitializers) { initializer.Initialize(formElement, property, deserializer); } formElement.LinePosition = (Position)(-1); } return(new FormElementLayout(WithMetadata(formElement, element))); } case "select": { var from = element.TryGetAttribute("from"); object itemsSource; string typeName; string displayPath; string valuePath; Type propertyType = null; if (!string.IsNullOrEmpty(from)) { if (from.StartsWith("type:")) { var qualifiedType = from.Substring("type:".Length); var nullable = false; if (qualifiedType.EndsWith("?")) { qualifiedType = qualifiedType.Substring(0, qualifiedType.Length - 1); nullable = true; } propertyType = Utilities.FindTypes(t => t.FullName == qualifiedType).FirstOrDefault(); itemsSource = propertyType ?? throw new InvalidOperationException($"Could not find type '{qualifiedType}'."); if (propertyType.IsValueType && nullable) { propertyType = typeof(Nullable <>).MakeGenericType(propertyType); itemsSource = propertyType; } typeName = element.TryGetAttribute("type"); } else { itemsSource = from; typeName = element.TryGetAttribute("type") ?? "string"; } displayPath = element.TryGetAttribute("displayPath"); valuePath = element.TryGetAttribute("valuePath"); } else { typeName = "string"; displayPath = "Name"; valuePath = "Value"; itemsSource = Utilities.GetSelectOptionsFromElement(element); } if (typeName != null && !TypeNames.TryGetValue(typeName, out propertyType)) { throw new InvalidOperationException($"Type '{typeName}' not found."); } if (propertyType.IsValueType && element.TryGetAttribute("nullable") != null && (!propertyType.IsGenericType || propertyType.GetGenericTypeDefinition() != typeof(Nullable <>))) { propertyType = typeof(Nullable <>).MakeGenericType(propertyType); } var fieldName = element.TryGetAttribute("name"); var attributes = new List <Attribute> { new SelectFromAttribute(itemsSource) { SelectionType = Utilities.TryParse(element.TryGetAttribute("as"), SelectionType.ComboBox), DisplayPath = displayPath, ValuePath = valuePath, ItemStringFormat = element.TryGetAttribute("itemStringFormat") }, Utilities.GetFieldAttributeFromElement(element), Utilities.GetBindingAttributeFromElement(element) }; attributes.AddRange(Utilities.GetValidatorsFromElement(element)); var property = new DynamicProperty(fieldName, propertyType, attributes.ToArray()); var deserializer = TryGetDeserializer(propertyType); formElement = Build(property, deserializer); if (formElement != null) { foreach (var initializer in FieldInitializers) { initializer.Initialize(formElement, property, deserializer); } formElement.LinePosition = (Position)(-1); } return(new FormElementLayout(WithMetadata(formElement, element))); } case "title": formElement = new TitleAttribute(element.GetAttributeOrValue("content")) { Icon = element.TryGetAttribute("icon") } .WithBaseProperties(element) .WithTextProperties(element) .GetElement(); return(new FormElementLayout(WithMetadata(formElement, element))); case "heading": formElement = new HeadingAttribute(element.GetAttributeOrValue("content")) { Icon = element.TryGetAttribute("icon") } .WithBaseProperties(element) .WithTextProperties(element) .GetElement(); return(new FormElementLayout(WithMetadata(formElement, element))); case "text": formElement = new TextAttribute(element.GetAttributeOrValue("content")) .WithBaseProperties(element) .WithTextProperties(element) .GetElement(); return(new FormElementLayout(WithMetadata(formElement, element))); case "error": formElement = new ErrorTextAttribute(element.GetAttributeOrValue("content")) .WithBaseProperties(element) .WithTextProperties(element) .GetElement(); return(new FormElementLayout(WithMetadata(formElement, element))); case "img": formElement = new ImageAttribute(element.TryGetAttribute("src")) { Width = element.TryGetAttribute("width"), Height = element.TryGetAttribute("height"), HorizontalAlignment = element.TryGetAttribute("align"), VerticalAlignment = element.TryGetAttribute("valign"), Stretch = element.TryGetAttribute("stretch"), StretchDirection = element.TryGetAttribute("direction") } .WithBaseProperties(element) .GetElement(); return(new FormElementLayout(WithMetadata(formElement, element))); case "br": formElement = new BreakAttribute { Height = element.TryGetAttribute("height") } .WithBaseProperties(element) .GetElement(); return(new FormElementLayout(WithMetadata(formElement, element))); case "hr": var hasMargin = element.TryGetAttribute("hasMargin"); formElement = (hasMargin != null ? new DividerAttribute(bool.Parse(hasMargin)) : new DividerAttribute()) .WithBaseProperties(element) .GetElement(); return(new FormElementLayout(WithMetadata(formElement, element))); case "action": formElement = Utilities.GetAction(element) .WithBaseProperties(element) .GetElement(); return(new FormElementLayout(WithMetadata(formElement, element))); default: throw new InvalidOperationException($"Unknown element '{element.Name.LocalName}'."); } } GridColumnLayout Column(XElement element) { var elements = element.Elements().ToList(); var child = elements.Count == 1 ? Row(elements[0]) : new Layout(elements.Select(Row)); return(new GridColumnLayout( child, Utilities.ParseDouble(element.TryGetAttribute("width"), 1d), Utilities.ParseDouble(element.TryGetAttribute("left"), 0d), Utilities.ParseDouble(element.TryGetAttribute("right"), 0d))); } GridLayout Grid(XElement element) { return(new GridLayout( element.Elements().Select(Column), Utilities.ParseDouble(element.TryGetAttribute("top"), 0d), Utilities.ParseDouble(element.TryGetAttribute("bottom"), 0d))); } InlineLayout Inline(XElement element) { return(new InlineLayout( element.Elements().Select(Terminal), Utilities.ParseDouble(element.TryGetAttribute("top"), 0d), Utilities.ParseDouble(element.TryGetAttribute("bottom"), 0d))); } ILayout Row(XElement element) { if (!string.Equals(element.Name.LocalName, "row", StringComparison.OrdinalIgnoreCase)) { return(Terminal(element)); } if (element .Elements() .All(e => string.Equals(e.Name.LocalName, "col", StringComparison.OrdinalIgnoreCase))) { return(Grid(element)); } return(Inline(element)); } Layout Layout(XElement element) { return(new Layout( element.Elements().Select(Row), Utilities.ParseThickness(element.TryGetAttribute("margin")), Utilities.TryParse(element.TryGetAttribute("valign"), VerticalAlignment.Stretch), Utilities.TryParse(element.TryGetAttribute("align"), HorizontalAlignment.Stretch), Utilities.ParseNullableDouble(element.TryGetAttribute("minHeight")), Utilities.ParseNullableDouble(element.TryGetAttribute("maxHeight")))); } var form = new FormDefinition(null); // null indicates dynamic type AddMetadata(form.Metadata, document.Root); form.FormRows.Add(new FormRow(true, 1) { Elements = { new FormElementContainer(0, 1, Layout(document.Root)) } }); if (freeze) { form.FreezeAll(); } return(form); }
public IReadOnlyList <IProductType> LoadTypes(ProductQuery query) { using (var uow = Factory.Create(ContextMode.AllOff)) { var baseSet = uow.GetRepository <IProductTypeEntityRepository>().Linq; var productsQuery = query.IncludeDeleted ? baseSet : baseSet.Active(); // Filter by type if (!string.IsNullOrEmpty(query.Type)) { if (query.ExcludeDerivedTypes) { productsQuery = productsQuery.Where(p => p.TypeName == query.Type); } else { var allTypes = ReflectionTool.GetPublicClasses <ProductType>(pt => { // TODO: Clean this up with full name and proper type compatibility var type = pt; // Check if any interface matches if (type.GetInterfaces().Any(inter => inter.Name == query.Type)) { return(true); } // Check if type or base type matches while (type != null) { if (type.Name == query.Type) { return(true); } type = type.BaseType; } return(false); }).Select(t => t.Name); productsQuery = productsQuery.Where(p => allTypes.Contains(p.TypeName)); } } // Filter by identifier if (!string.IsNullOrEmpty(query.Identifier)) { var identifierMatches = Regex.Match(query.Identifier, "(?<startCard>\\*)?(?<filter>\\w*)(?<endCard>\\*)?"); var identifier = identifierMatches.Groups["filter"].Value.ToLower(); if (identifierMatches.Groups["startCard"].Success && identifierMatches.Groups["endCard"].Success) { productsQuery = productsQuery.Where(p => p.Identifier.ToLower().Contains(identifier)); } else if (identifierMatches.Groups["startCard"].Success) { productsQuery = productsQuery.Where(p => p.Identifier.ToLower().EndsWith(identifier)); } else if (identifierMatches.Groups["endCard"].Success) { productsQuery = productsQuery.Where(p => p.Identifier.ToLower().StartsWith(identifier)); } else { productsQuery = productsQuery.Where(p => p.Identifier.ToLower() == identifier); } } // Filter by revision if (query.RevisionFilter == RevisionFilter.Latest) { var compareSet = baseSet.Active(); productsQuery = productsQuery.Where(p => p.Revision == compareSet.Where(compare => compare.Identifier == p.Identifier).Max(compare => compare.Revision)); } else if (query.RevisionFilter == RevisionFilter.Specific) { productsQuery = productsQuery.Where(p => p.Revision == query.Revision); } // Filter by name if (!string.IsNullOrEmpty(query.Name)) { productsQuery = productsQuery.Where(p => p.Name.ToLower().Contains(query.Name.ToLower())); } // Filter by recipe if (query.RecipeFilter == RecipeFilter.WithRecipe) { productsQuery = productsQuery.Where(p => p.Recipes.Any()); } else if (query.RecipeFilter == RecipeFilter.WithoutRecipes) { productsQuery = productsQuery.Where(p => p.Recipes.Count == 0); } // Apply selector switch (query.Selector) { case Selector.Parent: productsQuery = productsQuery.SelectMany(p => p.Parents).Where(p => p.Parent.Deleted == null) .Select(link => link.Parent); break; case Selector.Parts: productsQuery = productsQuery.SelectMany(p => p.Parts).Where(p => p.Parent.Deleted == null) .Select(link => link.Child); break; } // Include current version productsQuery = productsQuery.Include(p => p.CurrentVersion); // Execute the query var products = productsQuery.OrderBy(p => p.TypeName) .ThenBy(p => p.Identifier) .ThenBy(p => p.Revision).ToList(); // TODO: Use TypeWrapper with constructor delegate and isolate basic property conversion return(products.Where(p => TypeConstructors.ContainsKey(p.TypeName)).Select(p => { var instance = TypeConstructors[p.TypeName](); instance.Id = p.Id; instance.Identity = new ProductIdentity(p.Identifier, p.Revision); instance.Name = p.Name; return instance; }).ToList()); } }