public void Test_All_Variables_Are_Loaded()
        {
            _LibraryPluginManager.Activate(_SimpleDummyReference);

            // get the first available plugin
            ILibraryPluginData testLibraryPluginData = (from p in _LibraryPluginManager.AvailablePlugins
                                                        select p.Value).FirstOrDefault();

            // get the expected result
            // load a list of types from the plugin assebly that implement the IStaticExtension interface
            // count all properties that have a StaticVariableAttribute

            Type staticExtensionInterfaceType = typeof(IStaticExtension);

            var expectedStaticExtensionTypes = from t in Assembly.GetAssembly(typeof(FirstDummyStaticExtension)).GetTypes()
                                               where t.IsClass &&
                                               staticExtensionInterfaceType.IsAssignableFrom(t)
                                               select t;

            int expectedNumberOfVariables = 0;

            foreach (var extensionType in expectedStaticExtensionTypes)
            {
                var variableProperties = from m in extensionType.GetMembers()
                                         where m.MemberType == MemberTypes.Property &&
                                         m.GetCustomAttribute <StaticVariableAttribute>() != null
                                         select m;

                expectedNumberOfVariables += variableProperties.Count();
            }

            Assert.AreEqual(expectedNumberOfVariables, testLibraryPluginData.StaticExtensionContainer.Variables.Count);
        }
        public void SetupTest()
        {
            string solutionDirectoryPath = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(System.IO.Directory.GetCurrentDirectory())));

            _PluginDirectoryPath = Path.Combine(solutionDirectoryPath, @"_TestData\InterfaceBooster\LibraryPluginData");
            _PluginXmlFilePath   = Path.Combine(_PluginDirectoryPath, "plugin.xml");
            _LibraryPluginData   = LibraryPluginDataController.Load(_PluginXmlFilePath);
        }
        public static ILibraryPluginData Load(string pluginXmlFilePath)
        {
            LibraryPluginDataController controller = new LibraryPluginDataController(pluginXmlFilePath);

            ILibraryPluginData data = controller.LoadData();

            return(data);
        }
        public void Activate(LibraryPluginReference reference)
        {
            if (string.IsNullOrEmpty(PluginMainDirectoryPath))
            {
                throw new LibraryPluginManagerException(this, String.Format(
                                                            "A valid PluginMainDirectoryPath must be set before using the LibraryPluginManager. Path given: {0}",
                                                            PluginMainDirectoryPath));
            }

            ILibraryPluginData pluginData = (from d in _AvailablePlugins
                                             where d.Key.IdPlugin == reference.IdPlugin
                                             select d.Value).FirstOrDefault();

            // If the plugin data was found the plugin has already been initialized. So nothing must be done.
            // Otherwise the plugin must be searched on the filesystem and the assembly must be loaded.
            if (pluginData == null)
            {
                // check whether the SyneryIdentifier is unique

                var numberOfExistingPluginsWithTheSameIdentfier = (from i in _AvailablePlugins
                                                                   where i.Key.SyneryIdentifier == reference.SyneryIdentifier
                                                                   select i).Count();

                if (numberOfExistingPluginsWithTheSameIdentfier != 0)
                {
                    throw new LibraryPluginManagerException(this, String.Format(
                                                                "Plugin activation for SyneryIdentifier='{0}' failed. A plugin with the given identifier already exists. The identifier must be unique.",
                                                                reference.SyneryIdentifier));
                }

                // start loading plugin data

                // load plugin.xml
                pluginData = LoadLibraryPluginXmlData(reference);

                if (pluginData != null)
                {
                    // try to load the assembly by using the data from the plugin.xml
                    Assembly assembly = LoadAssembly(reference, pluginData);

                    // get the data of the StaticExtensions by reflection
                    pluginData.StaticExtensionContainer = LoadStaticExtensionContainer(reference, assembly);

                    // append the new plugin data to the dictionary
                    _AvailablePlugins.Add(reference, pluginData);
                }
                else
                {
                    throw new LibraryPluginManagerException(this, String.Format(
                                                                "Plugin activation for SyneryIdentifier='{0}' failed. The requested Plugin with Name='{1}' and Id='{2}' was not found.",
                                                                reference.SyneryIdentifier, reference.PluginName, reference.IdPlugin));
                }
            }
        }
        public void Test_Variable_HasSetter_Is_Recognized()
        {
            _LibraryPluginManager.Activate(_SimpleDummyReference);

            // get the first available plugin
            ILibraryPluginData testLibraryPluginData = (from p in _LibraryPluginManager.AvailablePlugins
                                                        select p.Value).FirstOrDefault();

            // get the expected result
            // load a list of types from the plugin assebly that implement the IStaticExtension interface
            // loop threw all properties that have a StaticVariableAttribute and check for a public setter

            Type staticExtensionInterfaceType = typeof(IStaticExtension);

            var expectedStaticExtensionTypes = from t in Assembly.GetAssembly(typeof(FirstDummyStaticExtension)).GetTypes()
                                               where t.IsClass &&
                                               staticExtensionInterfaceType.IsAssignableFrom(t)
                                               select t;

            List <PropertyInfo> expectedListOfPropertiesWithSetter = new List <PropertyInfo>();
            List <PropertyInfo> expectedListOfReadOnlyProperties   = new List <PropertyInfo>();

            foreach (var extensionType in expectedStaticExtensionTypes)
            {
                var propertiesWithSetter = from m in extensionType.GetProperties()
                                           where m.MemberType == MemberTypes.Property &&
                                           m.SetMethod != null &&
                                           m.SetMethod.IsPublic == true &&
                                           m.GetCustomAttribute <StaticVariableAttribute>() != null
                                           select m;
                var readOnlyProperties = from m in extensionType.GetProperties()
                                         where m.MemberType == MemberTypes.Property &&
                                         (m.SetMethod == null || m.SetMethod.IsPublic == false) &&
                                         m.GetCustomAttribute <StaticVariableAttribute>() != null
                                         select m;

                expectedListOfPropertiesWithSetter.AddRange(propertiesWithSetter);
                expectedListOfReadOnlyProperties.AddRange(readOnlyProperties);
            }

            IEnumerable <IStaticExtensionVariableData> listOfVariableDataWithSetter = from v in testLibraryPluginData.StaticExtensionContainer.Variables
                                                                                      where v.HasSetter == true
                                                                                      select v;


            IEnumerable <IStaticExtensionVariableData> listOfVariableDataWithoutSetter = from v in testLibraryPluginData.StaticExtensionContainer.Variables
                                                                                         where v.HasSetter == false
                                                                                         select v;

            Assert.AreEqual(expectedListOfPropertiesWithSetter.Count, listOfVariableDataWithSetter.Count());
            Assert.AreEqual(expectedListOfReadOnlyProperties.Count, listOfVariableDataWithoutSetter.Count());
        }
        private Assembly LoadAssembly(LibraryPluginReference reference, ILibraryPluginData pluginData)
        {
            Version availableInterfaceVersion = GetInterfaceAssemblyVersion();

            // check for the correct interface version
            // if the versions don't match the ProviderPlugin bases on another interface .dll-file than provided by the current runtime
            ILibraryPluginAssemblyData assemblyData = (from a in pluginData.Assemblies
                                                       where a.RequiredInterfaceVersion == availableInterfaceVersion
                                                       select a).FirstOrDefault();

            if (assemblyData != null)
            {
                Assembly assembly;
                string   assemblyFilePath = Path.Combine(pluginData.PluginDirectoryPath, assemblyData.Path);

                if (!File.Exists(assemblyFilePath))
                {
                    throw new LibraryPluginManagerException(this, String.Format(
                                                                "The given assembly of LibraryPlugin with name='{0}' and id='{1}' cannot be found. Assembly file path='{2}'.",
                                                                pluginData.Name, pluginData.Id, assemblyFilePath));
                }

                try
                {
                    // now we are ready to load the foreign assembly

                    assembly = Assembly.LoadFrom(assemblyFilePath);

                    return(assembly);
                }
                catch (Exception ex)
                {
                    // catch unexpected exceptions while loading the assembly to enrich the thrown exception with some additional information

                    throw new LibraryPluginManagerException(this, String.Format(
                                                                "An unexpected error occured while loading the LibraryPlugin with name='{0}' and id='{1}'. Assembly file path='{2}'.",
                                                                pluginData.Name, pluginData.Id, assemblyFilePath),
                                                            ex);
                }
            }
            else
            {
                throw new LibraryPluginManagerException(this, String.Format(
                                                            "No assembly found for the LibraryPlugin with name='{0}' and id='{1}' that supports the required interface version '{2}'",
                                                            reference.PluginName, reference.IdPlugin, availableInterfaceVersion.ToString()));
            }
        }
        private IStaticExtensionFunctionData FindFunctionDeclaration(ILibraryPluginData libraryPluginData, string functionIdentifier, Type[] listOfParameterTypes)
        {
            int numberOfParameterTypes = listOfParameterTypes.Count();

            // try to find function(s) with the same name with at least the same number of parameters as given
            var listOfFunctionData = (from f in libraryPluginData.StaticExtensionContainer.Functions
                                      where f.FullSyneryIdentifier == functionIdentifier &&
                                      f.Parameters.Count >= numberOfParameterTypes
                                      select f);

            // try to find the matching function signature
            // also consider that a parameter isn't set because it is optional
            foreach (var functionData in listOfFunctionData)
            {
                bool isMatching = true;

                for (int i = 0; i < functionData.Parameters.Count; i++)
                {
                    if (numberOfParameterTypes > i && listOfParameterTypes[i] != null)
                    {
                        // compare the types of the expected parameter and the given value
                        if (listOfParameterTypes[i] != functionData.Parameters[i].Type)
                        {
                            isMatching = false;
                        }
                    }
                    else
                    {
                        // no value given for the parameter: check whether parameter is optional
                        if (functionData.Parameters[i].IsOptional == false)
                        {
                            isMatching = false;
                        }
                    }
                }

                // the current function declaration seems to match -> return it
                if (isMatching == true)
                {
                    return(functionData);
                }
            }

            return(null);
        }
        public void Test_All_StaticExtensions_Are_Loaded()
        {
            _LibraryPluginManager.Activate(_SimpleDummyReference);

            // get the first available plugin
            ILibraryPluginData testLibraryPluginData = (from p in _LibraryPluginManager.AvailablePlugins
                                                        select p.Value).FirstOrDefault();

            // get the expected result
            // load a list of types from the plugin assebly that implement the IStaticExtension interface

            Type staticExtensionInterfaceType = typeof(IStaticExtension);

            var expectedStaticExtensionTypes = from t in Assembly.GetAssembly(typeof(FirstDummyStaticExtension)).GetTypes()
                                               where t.IsClass &&
                                               staticExtensionInterfaceType.IsAssignableFrom(t)
                                               select t;

            Assert.AreEqual(expectedStaticExtensionTypes.Count(), testLibraryPluginData.StaticExtensionContainer.Extensions.Count);
        }