/// <summary> /// Configure storage for <see cref="ProductInstance"/> /// </summary> public string ConfigureInstance(string instanceType) { var types = ReflectionTool.GetPublicClasses <ProductInstance>(); var instance = types.FirstOrDefault(p => p.Name == instanceType); if (instance == null) { return($"Found no instance type {instanceType ?? string.Empty}!\n" + "Available types: " + string.Join(", ", types.Select(t => t.Name))); } var result = string.Empty; if (Config.InstanceStrategies.Any(s => s.TargetType == instanceType)) { result += $"Product {instanceType} already has an InstanceStrategy configured. Overwriting configs is not supported!\n"; } else { var instanceConfig = StrategyConfig <IProductInstanceStrategy, ProductInstanceConfiguration, ProductInstance>(instance); if (instanceConfig == null) { result += $"Found no matching instance strategy for {instanceType}. Make sure you declared the '{nameof(StrategyConfigurationAttribute)}'!\n"; } else { Config.InstanceStrategies.Add(instanceConfig); result += $"Selected InstanceStrategy {instanceConfig.PluginName} for {instanceType}."; } } return(result); }
public ProductCustomization GetCustomization() { return(ExecuteCall <ProductCustomization>(delegate { return new ProductCustomization { ProductTypes = ReflectionTool .GetPublicClasses <ProductType>(new IsConfiguredFilter(Config.TypeStrategies).IsConfigured) .Select(Converter.ConvertProductType).ToArray(), RecipeTypes = ReflectionTool .GetPublicClasses <IProductRecipe>(new IsConfiguredFilter(Config.RecipeStrategies).IsConfigured) .Select(rt => new RecipeDefinitionModel { Name = rt.Name, DisplayName = rt.GetDisplayName() ?? rt.Name, HasWorkplans = typeof(IWorkplanRecipe).IsAssignableFrom(rt) }).ToArray(), Importers = ProductManager.Importers.Select(i => new ProductImporter { Name = i.Name, Parameters = ConvertParameters(i.Parameters) }).ToArray() }; })); }
/// <summary> /// Configure storage for <see cref="ProductRecipe"/> /// </summary> public string ConfigureRecipe(string recipeType) { var types = ReflectionTool.GetPublicClasses <IProductRecipe>(); var recipe = types.FirstOrDefault(p => p.Name == recipeType); if (recipe == null) { return($"Found no recipe type {recipeType ?? string.Empty}!\n" + "Available types: " + string.Join(", ", types.Select(t => t.Name))); } var result = string.Empty; if (Config.RecipeStrategies.Any(s => s.TargetType == recipeType)) { result += $"Recipe {recipeType} already has a RecipeStrategy configured. Overwriting configs is not supported!\n"; } else { // ProductionRecipe is technically not the correct base type, BUT it defines all relevant properties, which is the only thing that matters var recipeConfig = StrategyConfig <IProductRecipeStrategy, ProductRecipeConfiguration, ProductionRecipe>(recipe); if (recipeConfig == null) { result += $"Found no matching recipe strategy for {recipeType}. Make sure you declared the '{nameof(StrategyConfigurationAttribute)}'!\n"; } else { Config.RecipeStrategies.Add(recipeConfig); result += $"Selected RecipeStrategy {recipeConfig.PluginName} for {recipeType}."; } } return(result); }
public IProductRecipe ConvertRecipeBack(RecipeModel recipe, IProductType productType) { IProductRecipe productRecipe; if (recipe.Id == 0) { var type = ReflectionTool.GetPublicClasses <IProductRecipe>(t => t.Name == recipe.Type).First(); productRecipe = (IProductRecipe)Activator.CreateInstance(type); } else { productRecipe = RecipeManagement.Get(recipe.Id); } productRecipe.Name = recipe.Name; productRecipe.Revision = recipe.Revision; productRecipe.State = recipe.State; // Only load workplan if it changed var workplanRecipe = productRecipe as IWorkplanRecipe; if (workplanRecipe != null && workplanRecipe.Workplan?.Id != recipe.WorkplanId) { workplanRecipe.Workplan = WorkplanManagement.LoadWorkplan(recipe.WorkplanId); } if (productRecipe.Product == null) { productRecipe.Product = productType; } switch (recipe.Classification) { case RecipeClassificationModel.Unset: productRecipe.Classification = RecipeClassification.Unset; break; case RecipeClassificationModel.Default: productRecipe.Classification = RecipeClassification.Default; break; case RecipeClassificationModel.Alternative: productRecipe.Classification = RecipeClassification.Alternative; break; case RecipeClassificationModel.Intermediate: productRecipe.Classification = RecipeClassification.Intermediate; break; case RecipeClassificationModel.Part: productRecipe.Classification = RecipeClassification.Part; break; default: throw new ArgumentOutOfRangeException(); } EntryConvert.UpdateInstance(productRecipe, recipe.Properties, RecipeSerialization); return(productRecipe); }
/// <summary> /// Build the entire type tree and type cache /// </summary> private void BuildTypeTree() { // Start with all public types var allTypes = new List <Type>(); var registeredTypes = Container.GetRegisteredImplementations(typeof(IResource)).ToList(); // Load full type tree from registered resources foreach (var type in registeredTypes.Union(ReflectionTool.GetPublicClasses <Resource>())) { var buffer = type; // Exclude the different base types from "Moryx.Resources" from the type tree do { if (buffer.IsGenericType) // Generic base types appear multiple times, use only the generic type { buffer = buffer.GetGenericTypeDefinition(); } if (!allTypes.Contains(buffer)) { allTypes.Add(buffer); } buffer = buffer.BaseType; } while (buffer != null && buffer != typeof(Resource)); } // Convert tree to TypeNodes objects RootType = Convert(typeof(Resource), allTypes, registeredTypes); }
/// <inheritdoc /> public void Initialize() { LoggerManagement.ActivateLogging(this); var dbContextTypes = ReflectionTool.GetPublicClasses(typeof(DbContext), delegate(Type type) { var modelAttr = type.GetCustomAttribute <ModelConfiguratorAttribute>(); return(modelAttr != null); }); _knownModels = dbContextTypes .Select(dbContextType => new { DbContextType = dbContextType, ModelConfiguratorAttr = dbContextType.GetCustomAttribute <ModelConfiguratorAttribute>() }).Select(t => { var wrapper = new ModelWrapper { DbContextType = t.DbContextType, Configurator = (IModelConfigurator)Activator.CreateInstance(t.ModelConfiguratorAttr.ConfiguratorType) }; return(wrapper); }).ToArray(); foreach (var wrapper in _knownModels) { var configuratorType = wrapper.Configurator.GetType(); var logger = Logger.GetChild(configuratorType.Name, configuratorType); wrapper.Configurator.Initialize(wrapper.DbContextType, ConfigManager, logger); } }
public void SingleClassTest(Type type) { Type[] result = ReflectionTool.GetPublicClasses(type); Assert.AreEqual(1, result.Length, "Unexpected number of classes."); Assert.True(result.Contains(type)); }
public RecipeModel CreateRecipe(string recipeType) { // TODO: Use type wrapper var type = ReflectionTool.GetPublicClasses <IProductRecipe>(t => t.Name == recipeType).First(); var recipe = (IProductRecipe)Activator.CreateInstance(type); return(ConvertRecipe(recipe)); }
public IProductType CreateType(string type) { // TODO: Use type wrapper var productType = ReflectionTool.GetPublicClasses <ProductType>(t => t.Name == type).First(); var product = (ProductType)Activator.CreateInstance(productType); return(product); }
private IDictionary <string, Type> GetCapabilities() { #pragma warning disable 618 return(ReflectionTool.GetPublicClasses <ConcreteCapabilities>(type => _capabilitiesFilter(type)) .ToDictionary(t => t.Name, t => t)); #pragma warning restore 618 }
public void ChildClass1Test() { Type[] result = ReflectionTool.GetPublicClasses <ChildClass1>(); Assert.AreEqual(3, result.Length, "Unexpected number of classes."); Assert.True(result.Contains(typeof(ChildClass1))); Assert.True(result.Contains(typeof(GranChildClass1))); Assert.True(result.Contains(typeof(GranChildClass2))); }
public void BasicTest(Type type) { Type[] result = ReflectionTool.GetPublicClasses(type); Assert.AreEqual(5, result.Length, "Unexpected number of classes."); Assert.True(result.Contains(typeof(BaseClass))); Assert.True(result.Contains(typeof(ChildClass1))); Assert.True(result.Contains(typeof(ChildClass2))); Assert.True(result.Contains(typeof(GranChildClass1))); Assert.True(result.Contains(typeof(GranChildClass2))); }
/// <summary> /// Creates a new instance of <see cref="ModelSetupExecutor{TContext}"/> /// </summary> /// <param name="dbContextManager"></param> public ModelSetupExecutor(IDbContextManager dbContextManager) { _dbContextManager = dbContextManager; // Load ModelSetups TODO: Load internals _setups = ReflectionTool.GetPublicClasses <IModelSetup>(delegate(Type type) { // Try to read context from attribute var setupAttr = type.GetCustomAttribute <ModelSetupAttribute>(); return(setupAttr != null && setupAttr.TargetContext == typeof(TContext)); }).Select(s => (IModelSetup)Activator.CreateInstance((Type)s)).ToArray(); }
/// <inheritdoc /> protected override IProductType[] Import(DefaultImporterParameters parameters) { // TODO: Use type wrapper var type = ReflectionTool.GetPublicClasses <ProductType>(p => p.Name == parameters.ProductType) .First(); var productType = (ProductType)Activator.CreateInstance(type); productType.Identity = new ProductIdentity(parameters.Identifier, parameters.Revision); productType.Name = parameters.Name; return(new IProductType[] { productType }); }
/// <summary> /// Start the storage and load the type strategies /// </summary> public void Start() { _types = ReflectionTool.GetPublicClasses <ProductType>().ToDictionary(t => t.Name, t => t); // Create type strategies foreach (var config in Config.TypeStrategies) { var strategy = StrategyFactory.CreateTypeStrategy(config); TypeStrategies[config.TargetType] = strategy; TypeConstructors[config.TargetType] = ReflectionTool.ConstructorDelegate <ProductType>(strategy.TargetType); } // Create instance strategies foreach (var config in Config.InstanceStrategies) { var strategy = StrategyFactory.CreateInstanceStrategy(config); InstanceStrategies[config.TargetType] = strategy; } // Create link strategies foreach (var config in Config.LinkStrategies) { var strategy = StrategyFactory.CreateLinkStrategy(config); LinkStrategies[config.TargetType][config.PartName] = strategy; var property = strategy.TargetType.GetProperty(config.PartName); var linkType = property.PropertyType; // Extract element type from collections if (typeof(IEnumerable <IProductPartLink>).IsAssignableFrom(linkType)) { linkType = linkType.GetGenericArguments()[0]; } // Build generic type if (linkType.IsInterface && linkType.IsGenericType) { var genericElement = linkType.GetGenericArguments()[0]; linkType = typeof(ProductPartLink <>).MakeGenericType(genericElement); } LinkConstructors[$"{config.TargetType}.{config.PartName}"] = ReflectionTool.ConstructorDelegate <IProductPartLink>(linkType); } // Create recipe strategies foreach (var config in Config.RecipeStrategies) { var strategy = StrategyFactory.CreateRecipeStrategy(config); RecipeStrategies[config.TargetType] = strategy; RecipeConstructors[config.TargetType] = ReflectionTool.ConstructorDelegate <IProductRecipe>(strategy.TargetType); } }
/// <inheritdoc /> protected override Task <ProductImporterResult> Import(ProductImportContext context, DefaultImporterParameters parameters) { // TODO: Use type wrapper var type = ReflectionTool.GetPublicClasses <ProductType>(p => p.Name == parameters.ProductType) .First(); var productType = (ProductType)Activator.CreateInstance(type); productType.Identity = new ProductIdentity(parameters.Identifier, parameters.Revision); productType.Name = parameters.Name; return(Task.FromResult(new ProductImporterResult { ImportedTypes = new[] { productType } })); }
public ActionResult <long> SaveRecipe(RecipeModel recipe) { if (recipe == null) { return(BadRequest($"Recipe was null")); } var type = ReflectionTool.GetPublicClasses <IProductRecipe>(t => t.Name == recipe.Type) .FirstOrDefault(); if (type == null) { return(NotFound()); } var productRecipe = (IProductRecipe)Activator.CreateInstance(type); return(_productManagement.SaveRecipe(_productConverter.ConvertRecipeBack(recipe, productRecipe, null))); }
public ActionResult <long> SaveType(ProductModel newTypeModel) { if (newTypeModel == null) { return(BadRequest($"Modified type was null")); } var type = ReflectionTool.GetPublicClasses <ProductType>(t => t.Name == newTypeModel.Type) .FirstOrDefault(); if (type == null) { return(NotFound()); } var productType = (ProductType)Activator.CreateInstance(type); var newType = _productConverter.ConvertProductBack(newTypeModel, productType); return(_productManagement.SaveType(newType)); }
public ActionResult SaveInstance(ProductInstanceModel instanceModel) { if (instanceModel == null) { return(BadRequest($"Instance model was empty")); } var type = ReflectionTool.GetPublicClasses <IProductType>(t => t.Name == instanceModel.Type) .FirstOrDefault(); if (type == null) { return(NotFound()); } var productType = (IProductType)Activator.CreateInstance(type); var productInstance = _productConverter.ConvertProductInstanceBack(instanceModel, productType); _productManagement.SaveInstance(productInstance); return(Ok()); }
/// <inheritdoc /> public Resource Instantiate(string type) { if (_typeMap == null) { ReflectionTool.TestMode = true; _typeMap = ReflectionTool.GetPublicClasses <Resource>().ToDictionary(c => c.FullName, c => c); ReflectionTool.TestMode = false; } var instance = Activator.CreateInstance(_typeMap[type]) as Resource; if (instance == null) { throw new InvalidOperationException($"Cannot instantiate {type}"); } SetReferenceCollections(instance); instance.Logger = new DummyLogger(); return(instance); }
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 queryType = _types[query.Type]; var allTypes = ReflectionTool.GetPublicClasses(queryType).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.Select(p => { var instance = (ProductType)Activator.CreateInstance(_types[p.TypeName]); instance.Id = p.Id; instance.Identity = new ProductIdentity(p.Identifier, p.Revision); instance.Name = p.Name; return instance; }).ToList()); } }
/// <summary> /// Creates an new instance of <see cref="PossibleTypesAttribute"/> /// Searches for all public implementations of the given base types. /// </summary> public PossibleTypesAttribute(Type baseType) { _types = ReflectionTool.GetPublicClasses(baseType); }
public IProductType ConvertProductBack(ProductModel source, ProductType converted) { // Copy base values converted.Identity = new ProductIdentity(source.Identifier, source.Revision); converted.Name = source.Name; converted.State = source.State; // Save recipes var recipes = new List <IProductRecipe>(source.Recipes?.Length ?? 0); foreach (var recipeModel in source.Recipes ?? Enumerable.Empty <RecipeModel>()) { IProductRecipe productRecipe; if (recipeModel.Id == 0) { var type = ReflectionTool.GetPublicClasses <IProductRecipe>(t => t.Name == recipeModel.Type).First(); productRecipe = (IProductRecipe)Activator.CreateInstance(type); } else { productRecipe = RecipeManagement.Get(recipeModel.Id); } ConvertRecipeBack(recipeModel, productRecipe, converted); recipes.Add(productRecipe); } if (recipes.Any()) { RecipeManagement.Save(source.Id, recipes); } // Product is flat if (source.Properties is null) { return(converted); } // Copy extended properties var properties = converted.GetType().GetProperties(); EntryConvert.UpdateInstance(converted, source.Properties, ProductSerialization); // Copy Files ConvertFilesBack(converted, source, properties); // Convert parts foreach (var partConnector in source.Parts ?? Enumerable.Empty <PartConnector>()) { if (partConnector.Parts is null) { continue; } var prop = properties.First(p => p.Name == partConnector.Name); var value = prop.GetValue(converted); if (partConnector.IsCollection) { if (value == null) { value = Activator.CreateInstance(typeof(List <>) .MakeGenericType(prop.PropertyType.GetGenericArguments().First())); prop.SetValue(converted, value); } UpdateCollection((IList)value, partConnector.Parts); } else if (partConnector.Parts.Length == 1) { if (value == null) { value = Activator.CreateInstance(prop.PropertyType); prop.SetValue(converted, value); } UpdateReference((IProductPartLink)value, partConnector.Parts[0]); } else if (partConnector.Parts.Length == 0) { prop.SetValue(converted, null); } } return(converted); }
/// <summary> /// Add all necessary config entries for the product /// </summary> public string ConfigureType(string productType) { var productTypes = ReflectionTool.GetPublicClasses <ProductType>(); var product = productTypes.FirstOrDefault(p => p.Name == productType); if (product == null) { return($"Found no product type {productType ?? string.Empty}!\n" + "Available types: " + string.Join(", ", productTypes.Select(t => t.Name))); } var result = string.Empty; // First try to select the best type strategy if (Config.TypeStrategies.Any(s => s.TargetType == productType)) { result += $"Product {productType} already has a TypeStrategy configured. Overwriting configs is not supported!\n"; } else { var typeConfig = StrategyConfig <IProductTypeStrategy, ProductTypeConfiguration, ProductType>(product); if (typeConfig == null) { result += $"Found no matching type strategy for {productType}. Make sure you declared the '{nameof(StrategyConfigurationAttribute)}'!\n"; } else { Config.TypeStrategies.Add(typeConfig); result += $"Selected TypeStrategy {typeConfig.PluginName} for {productType}."; } } // Configure part links // TODO: Use type wrapper var links = product.GetProperties() .Where(p => typeof(IProductPartLink).IsAssignableFrom(p.PropertyType) || typeof(IEnumerable <IProductPartLink>).IsAssignableFrom(p.PropertyType)); foreach (var link in links) { if (Config.LinkStrategies.Any(s => s.TargetType == productType && s.PartName == link.Name)) { result += $"Product {productType} already has a LinkStrategy for {link.Name}. \n"; } else { var linkType = link.PropertyType; if (typeof(IEnumerable <IProductPartLink>).IsAssignableFrom(linkType)) { linkType = linkType.GetGenericArguments()[0]; } var linkConfig = StrategyConfig <IProductLinkStrategy, ProductLinkConfiguration, ProductPartLink>(linkType); if (linkConfig == null) { result += $"Found no matching instance strategy for {productType}. Make sure you declared the '{nameof(StrategyConfigurationAttribute)}'!\n"; } else { linkConfig.TargetType = productType; linkConfig.PartName = link.Name; Config.LinkStrategies.Add(linkConfig); result += $"Selected LinkStrategy {linkConfig.PluginName} for {productType}.{link.Name}."; } } } return(result); }
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 type properties properties if (query.PropertyFilters != null && TypeStrategies[query.Type] is IProductTypeSearch typeSearch) { var targetType = typeSearch.TargetType; // Make generic method for the target type var genericMethod = typeof(IProductTypeSearch).GetMethod(nameof(IProductTypeSearch.TransformSelector)); var method = genericMethod.MakeGenericMethod(targetType); foreach (var propertyFilter in query.PropertyFilters) { var expression = ConvertPropertyFilter(targetType, propertyFilter); var columnExpression = (Expression <Func <IGenericColumns, bool> >)method.Invoke(typeSearch, new object[] { expression }); var versionExpression = AsVersionExpression(columnExpression); productsQuery = productsQuery.Where(versionExpression); } } } // 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()); } }
private IDictionary <string, Type> GetCapabilities() { return(ReflectionTool.GetPublicClasses <ConcreteCapabilities>(type => _capabilitiesFilter(type)) .ToDictionary(t => t.Name, t => t)); }