private Tuple <IEnumerable <IAssociationSpecImmutable>, IImmutableDictionary <string, ITypeSpecBuilder> > CreateCollectionSpecs(IEnumerable <PropertyInfo> collectionProperties, IObjectSpecImmutable spec, IImmutableDictionary <string, ITypeSpecBuilder> metamodel) { var specs = new List <IAssociationSpecImmutable>(); foreach (PropertyInfo property in collectionProperties) { IIdentifier identifier = new IdentifierImpl(FullName, property.Name); // create a collection property spec Type returnType = property.PropertyType; Type defaultType = typeof(object); var result = reflector.LoadSpecification(returnType, metamodel); metamodel = result.Item2; var returnSpec = result.Item1 as IObjectSpecImmutable; result = reflector.LoadSpecification(defaultType, metamodel); metamodel = result.Item2; var defaultSpec = result.Item1 as IObjectSpecImmutable; var collection = ImmutableSpecFactory.CreateOneToManyAssociationSpecImmutable(identifier, spec, returnSpec, defaultSpec); metamodel = FacetFactorySet.Process(reflector, property, new IntrospectorMethodRemover(methods), collection, FeatureType.Collections, metamodel); specs.Add(collection); } return(new Tuple <IEnumerable <IAssociationSpecImmutable>, IImmutableDictionary <string, ITypeSpecBuilder> >(specs, metamodel)); }
/// <summary> /// Creates a list of Association fields for all the properties that use NakedObjects. /// </summary> private Tuple <IEnumerable <IAssociationSpecImmutable>, IImmutableDictionary <string, ITypeSpecBuilder> > CreateRefPropertySpecs(IEnumerable <PropertyInfo> foundProperties, IObjectSpecImmutable spec, IImmutableDictionary <string, ITypeSpecBuilder> metamodel) { var specs = new List <IAssociationSpecImmutable>(); foreach (PropertyInfo property in foundProperties) { // create a reference property spec var identifier = new IdentifierImpl(FullName, property.Name); Type propertyType = property.PropertyType; var result = reflector.LoadSpecification(propertyType, metamodel); metamodel = result.Item2; var propertySpec = result.Item1; if (propertySpec is IServiceSpecImmutable) { throw new ReflectionException(Log.LogAndReturn($"Type {propertyType.Name} is a service and cannot be used in public property {property.Name} on type {property.DeclaringType?.Name}. If the property is intended to be an injected service it should have a protected get.")); } var referenceProperty = ImmutableSpecFactory.CreateOneToOneAssociationSpecImmutable(identifier, spec, propertySpec as IObjectSpecImmutable); // Process facets for the property metamodel = FacetFactorySet.Process(reflector, property, new IntrospectorMethodRemover(methods), referenceProperty, FeatureType.Properties, metamodel); specs.Add(referenceProperty); } return(new Tuple <IEnumerable <IAssociationSpecImmutable>, IImmutableDictionary <string, ITypeSpecBuilder> >(specs, metamodel)); }
private Tuple <IActionSpecImmutable[], IImmutableDictionary <string, ITypeSpecBuilder> > FindActionMethods(ITypeSpecImmutable spec, IImmutableDictionary <string, ITypeSpecBuilder> metamodel) { var actionSpecs = new List <IActionSpecImmutable>(); var actions = FacetFactorySet.FindActions(methods.Where(m => m != null).ToArray(), reflector.ClassStrategy).Where(a => !FacetFactorySet.Filters(a, reflector.ClassStrategy)).ToArray(); methods = methods.Except(actions).ToArray(); // ReSharper disable once ForCanBeConvertedToForeach // kepp for look as actions are nulled out within loop for (int i = 0; i < actions.Length; i++) { MethodInfo actionMethod = actions[i]; // actions are potentially being nulled within this loop if (actionMethod != null) { string fullMethodName = actionMethod.Name; Type[] parameterTypes = actionMethod.GetParameters().Select(parameterInfo => parameterInfo.ParameterType).ToArray(); // build action & its parameters if (actionMethod.ReturnType != typeof(void)) { metamodel = reflector.LoadSpecification(actionMethod.ReturnType, metamodel).Item2; } IIdentifier identifier = new IdentifierImpl(FullName, fullMethodName, actionMethod.GetParameters().ToArray()); //IActionParameterSpecImmutable[] actionParams = parameterTypes. // Select(pt => ImmutableSpecFactory.CreateActionParameterSpecImmutable(reflector.LoadSpecification<IObjectSpecImmutable>(pt, metamodel), identifier)).ToArray(); var actionParams = new List <IActionParameterSpecImmutable>(); foreach (var pt in parameterTypes) { var result = reflector.LoadSpecification(pt, metamodel); metamodel = result.Item2; var ospec = result.Item1 as IObjectSpecImmutable; var actionSpec = ImmutableSpecFactory.CreateActionParameterSpecImmutable(ospec, identifier); actionParams.Add(actionSpec); } var action = ImmutableSpecFactory.CreateActionSpecImmutable(identifier, spec, actionParams.ToArray()); // Process facets on the action & parameters metamodel = FacetFactorySet.Process(reflector, actionMethod, new IntrospectorMethodRemover(actions), action, FeatureType.Actions, metamodel); for (int l = 0; l < actionParams.Count; l++) { metamodel = FacetFactorySet.ProcessParams(reflector, actionMethod, l, actionParams[l], metamodel); } actionSpecs.Add(action); } } return(new Tuple <IActionSpecImmutable[], IImmutableDictionary <string, ITypeSpecBuilder> >(actionSpecs.ToArray(), metamodel)); }
public IImmutableDictionary <string, ITypeSpecBuilder> IntrospectType(Type typeToIntrospect, ITypeSpecImmutable spec, IImmutableDictionary <string, ITypeSpecBuilder> metamodel) { if (!TypeUtils.IsPublic(typeToIntrospect)) { throw new ReflectionException(Log.LogAndReturn(string.Format(Resources.NakedObjects.DomainClassReflectionError, typeToIntrospect))); } IntrospectedType = typeToIntrospect; SpecificationType = GetSpecificationType(typeToIntrospect); properties = typeToIntrospect.GetProperties(); methods = GetNonPropertyMethods(); identifier = new IdentifierImpl(FullName); // Process facets at object level // this will also remove some methods, such as the superclass methods. var methodRemover = new IntrospectorMethodRemover(methods); metamodel = FacetFactorySet.Process(reflector, IntrospectedType, methodRemover, spec, metamodel); if (SuperclassType != null && ClassStrategy.IsTypeToBeIntrospected(SuperclassType)) { var result = reflector.LoadSpecification(SuperclassType, metamodel); metamodel = result.Item2; Superclass = result.Item1; } AddAsSubclass(spec); var interfaces = new List <ITypeSpecBuilder>(); foreach (Type interfaceType in InterfacesTypes) { if (interfaceType != null && ClassStrategy.IsTypeToBeIntrospected(interfaceType)) { var result = reflector.LoadSpecification(interfaceType, metamodel); metamodel = result.Item2; var interfaceSpec = result.Item1; interfaceSpec.AddSubclass(spec); interfaces.Add(interfaceSpec); } } Interfaces = interfaces.ToArray(); metamodel = IntrospectPropertiesAndCollections(spec, metamodel); metamodel = IntrospectActions(spec, metamodel); return(metamodel); }