Esempio n. 1
0
        private MsilFile GetWrapperSource(PluginType pluginType, string[] methodsToRemoveFromWrapper, string pluginAssemblyName, string pluginClass)
        {
            var wrapperType = Wrapper[pluginType];

            var exportedMethods = new AssemblyParser(wrapperType.Assembly).GetExportedMethods();

            exportedMethods = exportedMethods.Where(_ => !methodsToRemoveFromWrapper.Contains(_.ExportName)).ToArray();

            var wrapper = GetMsilFile(wrapperType.Assembly.Location, cache: false, il => il
                                      .Replace("[TcPluginBase]TcPluginBase.PluginClassPlaceholder", $"[{pluginAssemblyName}]{pluginClass}")
                                      .Replace("[TcPluginBase]", "")
                                      );

            var dllExportAttribute = $".custom instance void {typeof(DllExportAttribute).FullName}";

            var count = 1;

            foreach (var method in wrapper.Classes.SelectMany(_ => _.Methods).Where(_ => _.Public && _.Static))
            {
                var index = method.Lines.ToList().FindIndex(_ => _.ToString().Contains(dllExportAttribute));

                if (index != -1)
                {
                    var exportName = exportedMethods.FirstOrDefault(x => x.Method == method.Name).ExportName;

                    if (!string.IsNullOrEmpty(exportName))
                    {
                        method.Lines[index] = $".export [{count++}] as '{exportName}'";
                    }
                }
            }

            return(wrapper);
        }
Esempio n. 2
0
        internal (PluginType PluginType, string[] ExcludedMethods, string pluginClass, AssemblyName pluginAssemblyName) AnalyzeAssembly(FileInfo assemblyFile)
        {
            AppDomain.CurrentDomain.AssemblyResolve += new RelativeAssemblyResolver(assemblyFile.FullName).AssemblyResolve;
            var assembly = Assembly.LoadFile(assemblyFile.FullName);

            var parser          = new AssemblyParser(assembly);
            var implementations = parser.GetImplementations();

            // get excluded
            var excludedMethods = new List <string>();

            foreach (var implementation in implementations)
            {
                var pluginType    = implementation.Key;
                var pluginClasses = implementation.Value;

                if (pluginClasses.Length > 1)
                {
                    throw new Exception($"Too many {pluginType} Plugin implementations in one project!! Found implementations in: {string.Join(", ", pluginClasses.Select(_ => _.FullName))}");
                }

                excludedMethods.AddRange(parser.GetExcludedMethods(pluginClasses[0], pluginType));
            }

            // check pluginType
            Type pluginClass;
            var  pluginTypes = implementations.Select(_ => _.Key).ToArray();

            switch (pluginTypes.Length)
            {
            case 0:
                throw new Exception("No Plugin implementation found!!");

            case 1:
                // this is valid
                pluginClass = implementations.FirstOrDefault().Value.Single();

                if (pluginTypes[0] == PluginType.FileSystem)
                {
                    // exclude ContentPlugin methods from FileSystem plugin
                    excludedMethods.AddRange(parser.GetExcludedMethods(null, PluginType.Content));
                }

                break;

            case 2 when pluginTypes.Contains(PluginType.FileSystem) && pluginTypes.Contains(PluginType.Content):
                pluginTypes = new[] { PluginType.FileSystem };
                pluginClass = implementations.FirstOrDefault(_ => _.Key == PluginType.FileSystem).Value.Single();
                break;

            default:
                throw new Exception("Too Many or invalid combination of Plugin implementations found!!");
            }

            var plgType = pluginTypes[0];

            return(plgType, excludedMethods.Distinct().ToArray(), pluginClass.FullName, pluginClass.Assembly.GetName());
        }