<commit_before>﻿using Microsoft.Practices.Unity;
using ModuleInject.Interfaces;
using ModuleInject.Utility;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;

namespace ModuleInject.Module
{
    internal static class ModuleResolver
    {
        public static void Resolve<IModule, TModule>(TModule module, IUnityContainer container)
            where TModule : IModule
            where IModule : IInjectionModule
        {
            Type moduleInterfaceType = typeof(IModule);

            if (!moduleInterfaceType.IsInterface)
            {
                throw new ModuleInjectException("Modules must always have an Interface");
            }

            var submodulePropertyInfos = GetModuleProperties<IModule, TModule>(true);
            foreach (var submodulePropInfo in submodulePropertyInfos)
            {
                TryResolveComponent<IModule, TModule>(module, container, submodulePropInfo);

                TryResolveSubmodule<IModule, TModule>(module, container, submodulePropInfo);
            }

            foreach (var propInfo in GetModuleProperties<IModule, TModule>(false))
            {
                if (!propInfo.PropertyType.IsInterface)
                {
                    CommonFunctions.ThrowPropertyAndTypeException<TModule>(Errors.ModuleResolver_PropertyIsNoInterface, propInfo.Name);
                }

                TryResolveComponent<IModule, TModule>(module, container, propInfo);
            }
        }

        private static IEnumerable<PropertyInfo> GetModuleProperties<IModule, TModule>(bool thatAreModules)
            where TModule : IModule
        {
            Type moduleType = typeof(TModule);
            Type moduleInterface = typeof(IModule);
            Type injectionModuleType = typeof(IInjectionModule);

            var interfaceProperties = moduleInterface.GetPropertiesRecursive()
                                                     .Where(p =>
                                                      {
                                                          var searchedInterface = p.PropertyType.GetInterface(injectionModuleType.Name, false);
                                                          bool isModule = searchedInterface != null;
                                                          return thatAreModules ? isModule : !isModule;
                                                      })
                                                     .Select(p => moduleType.GetProperty(p.Name));

            var privateProperties = moduleType.GetPropertiesRecursive(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                                              .Where(p =>
                                              {
                                                  bool isPrivate = p.GetCustomAttributes(typeof(PrivateComponentAttribute), false).Length > 0;
                                                  var searchedInterface = p.PropertyType.GetInterface(injectionModuleType.Name, false);
                                                  bool isModule = searchedInterface != null;<commit_msg>Removed restriction that all properties must have interfaces.<commit_after>﻿using Microsoft.Practices.Unity;
using ModuleInject.Interfaces;
using ModuleInject.Utility;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;

namespace ModuleInject.Module
{
    internal static class ModuleResolver
    {
        public static void Resolve<IModule, TModule>(TModule module, IUnityContainer container)
            where TModule : IModule
            where IModule : IInjectionModule
        {
            Type moduleInterfaceType = typeof(IModule);

            if (!moduleInterfaceType.IsInterface)
            {
                throw new ModuleInjectException("Modules must always have an Interface");
            }

            var submodulePropertyInfos = GetModuleProperties<IModule, TModule>(true);
            foreach (var submodulePropInfo in submodulePropertyInfos)
            {
                TryResolveComponent<IModule, TModule>(module, container, submodulePropInfo);

                TryResolveSubmodule<IModule, TModule>(module, container, submodulePropInfo);
            }

            foreach (var propInfo in GetModuleProperties<IModule, TModule>(false))
            {
                //if (!propInfo.PropertyType.IsInterface)
                //{
                //    CommonFunctions.ThrowPropertyAndTypeException<TModule>(Errors.ModuleResolver_PropertyIsNoInterface, propInfo.Name);
                //}

                TryResolveComponent<IModule, TModule>(module, container, propInfo);
            }
        }

        private static IEnumerable<PropertyInfo> GetModuleProperties<IModule, TModule>(bool thatAreModules)
            where TModule : IModule
        {
            Type moduleType = typeof(TModule);
            Type moduleInterface = typeof(IModule);
            Type injectionModuleType = typeof(IInjectionModule);

            var interfaceProperties = moduleInterface.GetPropertiesRecursive()
                                                     .Where(p =>
                                                      {
                                                          var searchedInterface = p.PropertyType.GetInterface(injectionModuleType.Name, false);
                                                          bool isModule = searchedInterface != null;
                                                          return thatAreModules ? isModule : !isModule;
                                                      })
                                                     .Select(p => moduleType.GetProperty(p.Name));

            var privateProperties = moduleType.GetPropertiesRecursive(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                                              .Where(p =>
                                              {
                                                  bool isPrivate = p.GetCustomAttributes(typeof(PrivateComponentAttribute), false).Length > 0;
                                                  var searchedInterface = p.PropertyType.GetInterface(injectionModuleType.Name, false);
                                                  bool isModule = searchedInterface != null;
{'fraction_non_alphanumeric': 0.06488076803964075, 'fraction_numerical': 0.0003096934035305048, 'mean_word_length': 1.5479289940828402, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 48, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6871454', 'n_tokens_mistral': 1281, 'n_tokens_neox': 1272, 'n_words': 280}