示例#1
0
        /// <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);
        }
示例#2
0
 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()
         };
     }));
 }
示例#3
0
        /// <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);
        }
示例#6
0
        /// <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();
        }
示例#14
0
        /// <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 });
        }
示例#15
0
        /// <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());
        }
示例#20
0
        /// <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);
        }
示例#21
0
        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());
            }
        }
示例#22
0
 /// <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);
 }
示例#23
0
        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);
        }
示例#24
0
        /// <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);
        }
示例#25
0
        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());
            }
        }
示例#26
0
 private IDictionary <string, Type> GetCapabilities()
 {
     return(ReflectionTool.GetPublicClasses <ConcreteCapabilities>(type => _capabilitiesFilter(type))
            .ToDictionary(t => t.Name, t => t));
 }