diff --git a/core/diagnostics/DiagnosticScenarios/Controllers/DiagnosticScenarios.cs b/core/diagnostics/DiagnosticScenarios/Controllers/DiagnosticScenarios.cs index 4e39f71058f..453d9095a7f 100644 --- a/core/diagnostics/DiagnosticScenarios/Controllers/DiagnosticScenarios.cs +++ b/core/diagnostics/DiagnosticScenarios/Controllers/DiagnosticScenarios.cs @@ -12,8 +12,8 @@ namespace testwebapi.Controllers [ApiController] public class DiagScenarioController : ControllerBase { - var o1 = new object(); - var o2 = new object(); + object o1 = new object(); + object o2 = new object(); private static Processor p = new Processor(); diff --git a/core/tutorials/Unloading/Host/Host.csproj b/core/tutorials/Unloading/Host/Host.csproj deleted file mode 100644 index 67752e84b07..00000000000 --- a/core/tutorials/Unloading/Host/Host.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - Exe - netcoreapp3.0 - - - - - - - diff --git a/core/tutorials/Unloading/Host/Program.cs b/core/tutorials/Unloading/Host/Program.cs deleted file mode 100644 index 898e822bee8..00000000000 --- a/core/tutorials/Unloading/Host/Program.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System; -using System.IO; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.Loader; - -namespace Host -{ - // This is a collectible (unloadable) AssemblyLoadContext that loads the dependencies - // of the plugin from the plugin's binary directory. - class HostAssemblyLoadContext : AssemblyLoadContext - { - // Resolver of the locations of the assemblies that are dependencies of the - // main plugin assembly. - private AssemblyDependencyResolver _resolver; - - public HostAssemblyLoadContext(string pluginPath) : base(isCollectible: true) - { - _resolver = new AssemblyDependencyResolver(pluginPath); - } - - // The Load method override causes all the dependencies present in the plugin's binary directory to get loaded - // into the HostAssemblyLoadContext together with the plugin assembly itself. - // NOTE: The Interface assembly must not be present in the plugin's binary directory, otherwise we would - // end up with the assembly being loaded twice. Once in the default context and once in the HostAssemblyLoadContext. - // The types present on the host and plugin side would then not match even though they would have the same names. - protected override Assembly Load(AssemblyName name) - { - string assemblyPath = _resolver.ResolveAssemblyToPath(name); - if (assemblyPath != null) - { - Console.WriteLine($"Loading assembly {assemblyPath} into the HostAssemblyLoadContext"); - return LoadFromAssemblyPath(assemblyPath); - } - - return null; - } - } - - class Program - { - // It is important to mark this method as NoInlining, otherwise the JIT could decide - // to inline it into the Main method. That could then prevent successful unloading - // of the plugin because some of the MethodInfo / Type / Plugin.Interface / HostAssemblyLoadContext - // instances may get lifetime extended beyond the point when the plugin is expected to be - // unloaded. - [MethodImpl(MethodImplOptions.NoInlining)] - static void ExecuteAndUnload(string assemblyPath, out WeakReference alcWeakRef) - { - // Create the unloadable HostAssemblyLoadContext - var alc = new HostAssemblyLoadContext(assemblyPath); - - // Create a weak reference to the AssemblyLoadContext that will allow us to detect - // when the unload completes. - alcWeakRef = new WeakReference(alc); - - // Load the plugin assembly into the HostAssemblyLoadContext. - // NOTE: the assemblyPath must be an absolute path. - Assembly a = alc.LoadFromAssemblyPath(assemblyPath); - - // Get the plugin interface by calling the PluginClass.GetInterface method via reflection. - Type pluginType = a.GetType("Plugin.PluginClass"); - MethodInfo getInterface = pluginType.GetMethod("GetInterface", BindingFlags.Static | BindingFlags.Public); - Plugin.Interface plugin = (Plugin.Interface)getInterface.Invoke(null, null); - - // Now we can call methods of the plugin using the interface - string result = plugin.GetMessage(); - Plugin.Version version = plugin.GetVersion(); - - Console.WriteLine($"Response from the plugin: GetVersion(): {version}, GetMessage(): {result}"); - - // This initiates the unload of the HostAssemblyLoadContext. The actual unloading doesn't happen - // right away, GC has to kick in later to collect all the stuff. - alc.Unload(); - } - - static void Main(string[] args) - { - WeakReference hostAlcWeakRef; - string currentAssemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); -#if DEBUG - string configName = "Debug"; -#else - string configName = "Release"; -#endif - string pluginFullPath = Path.Combine(currentAssemblyDirectory, $"..\\..\\..\\..\\Plugin\\bin\\{configName}\\netcoreapp3.0\\Plugin.dll"); - ExecuteAndUnload(pluginFullPath, out hostAlcWeakRef); - - // Poll and run GC until the AssemblyLoadContext is unloaded. - // You don't need to do that unless you want to know when the context - // got unloaded. You can just leave it to the regular GC. - for (int i = 0; hostAlcWeakRef.IsAlive && (i < 10); i++) - { - GC.Collect(); - GC.WaitForPendingFinalizers(); - } - - Console.WriteLine($"Unload success: {!hostAlcWeakRef.IsAlive}"); - } - } -} diff --git a/core/tutorials/Unloading/Host/Properties/launchSettings.json b/core/tutorials/Unloading/Host/Properties/launchSettings.json deleted file mode 100644 index c61d3a8ef7e..00000000000 --- a/core/tutorials/Unloading/Host/Properties/launchSettings.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "profiles": { - "Host": { - "commandName": "Project" - } - } -} \ No newline at end of file diff --git a/core/tutorials/Unloading/Interface/Interface.cs b/core/tutorials/Unloading/Interface/Interface.cs deleted file mode 100644 index 2fe8f8446b0..00000000000 --- a/core/tutorials/Unloading/Interface/Interface.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; - -namespace Plugin -{ - public struct Version - { - public Version(int major, int minor) - { - Major = major; - Minor = minor; - } - - public int Major { get; } - public int Minor { get; } - - public override string ToString() - { - return $"({Major}.{Minor})"; - } - } - - // The Interface is defined in an Assembly shared between the host and the plugin. - // That makes calling functions from the plugin easier (without having to use reflection - // to invoke all of the functions - we just use reflection once to get the Interface) - // NOTE: - // The Assembly that defines the Interface must be loaded into the AssemblyLoadContext - // of the host only. If it got loaded twice - once into the AssemblyLoadContext in which - // the plugin is loaded and once into the default AssemblyLoadContext where the host is loaded, - // the Interface would become two different types and it would not be possible to - // use Interface instance created on the plugin side on the host side - public interface Interface - { - Version GetVersion(); - string GetMessage(); - } -} diff --git a/core/tutorials/Unloading/Interface/Interface.csproj b/core/tutorials/Unloading/Interface/Interface.csproj deleted file mode 100644 index ea83d29686c..00000000000 --- a/core/tutorials/Unloading/Interface/Interface.csproj +++ /dev/null @@ -1,7 +0,0 @@ - - - - netcoreapp3.0 - - - diff --git a/core/tutorials/Unloading/Plugin/Plugin.csproj b/core/tutorials/Unloading/Plugin/Plugin.csproj deleted file mode 100644 index 80afe31d26f..00000000000 --- a/core/tutorials/Unloading/Plugin/Plugin.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - - netcoreapp3.0 - - - - - - false - - - - - diff --git a/core/tutorials/Unloading/Plugin/PluginClass.cs b/core/tutorials/Unloading/Plugin/PluginClass.cs deleted file mode 100644 index 9f7741b5821..00000000000 --- a/core/tutorials/Unloading/Plugin/PluginClass.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Runtime.Loader; - -namespace Plugin -{ - public class PluginClass : Interface - { - public static Interface GetInterface() - { - PluginClass plugin = new PluginClass(); - - // We register handler for the Unloading event of the context that we are running in - // so that we can perform cleanup of stuff that would otherwise prevent unloading - // (Like freeing GCHandles for objects of types loaded into the unloadable AssemblyLoadContext, - // terminating threads running code in assemblies loaded into the unloadable AssemblyLoadContext, - // etc.) - // NOTE: this is optional and likely not required for basic scenarios - Assembly currentAssembly = Assembly.GetExecutingAssembly(); - AssemblyLoadContext currentContext = AssemblyLoadContext.GetLoadContext(currentAssembly); - currentContext.Unloading += OnPluginUnloadingRequested; - - return plugin; - } - - private static void OnPluginUnloadingRequested(AssemblyLoadContext obj) - { - PluginDependency.Logger.LogMessage("Cleanup of stuff preventing unloading"); - } - - // Plugin interface methods implementation - - public string GetMessage() - { - return "Hello from the unloadable plugin"; - } - - public Version GetVersion() - { - return new Version(1, 0); - } - } -} diff --git a/core/tutorials/Unloading/PluginDependency/Logger.cs b/core/tutorials/Unloading/PluginDependency/Logger.cs deleted file mode 100644 index ba562e58ba0..00000000000 --- a/core/tutorials/Unloading/PluginDependency/Logger.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace PluginDependency -{ - // This is a simple class to write message to console. It is present to demostrate - // how a dependency of the plugin gets loaded into the HostAssemblyLoadContext - public class Logger - { - public static void LogMessage(string msg) - { - Console.WriteLine(msg); - } - } -} diff --git a/core/tutorials/Unloading/PluginDependency/PluginDependency.csproj b/core/tutorials/Unloading/PluginDependency/PluginDependency.csproj deleted file mode 100644 index ea83d29686c..00000000000 --- a/core/tutorials/Unloading/PluginDependency/PluginDependency.csproj +++ /dev/null @@ -1,7 +0,0 @@ - - - - netcoreapp3.0 - - - diff --git a/core/tutorials/Unloading/Unloading.sln b/core/tutorials/Unloading/Unloading.sln deleted file mode 100644 index 742b9ee0f53..00000000000 --- a/core/tutorials/Unloading/Unloading.sln +++ /dev/null @@ -1,42 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.28516.95 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Host", "Host\Host.csproj", "{7C1BDD5C-0167-4682-B67B-4D1AFB874F09}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Plugin", "Plugin\Plugin.csproj", "{89ED8F97-E90B-453E-9086-130FAC5B99A9}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Interface", "Interface\Interface.csproj", "{C9BCDE8B-51BA-40A6-B7A1-186F6C6B6CCE}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginDependency", "PluginDependency\PluginDependency.csproj", "{0DFE9D18-D6B3-4097-AF87-D06B1B9DB4FA}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7C1BDD5C-0167-4682-B67B-4D1AFB874F09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7C1BDD5C-0167-4682-B67B-4D1AFB874F09}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7C1BDD5C-0167-4682-B67B-4D1AFB874F09}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7C1BDD5C-0167-4682-B67B-4D1AFB874F09}.Release|Any CPU.Build.0 = Release|Any CPU - {89ED8F97-E90B-453E-9086-130FAC5B99A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {89ED8F97-E90B-453E-9086-130FAC5B99A9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {89ED8F97-E90B-453E-9086-130FAC5B99A9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {89ED8F97-E90B-453E-9086-130FAC5B99A9}.Release|Any CPU.Build.0 = Release|Any CPU - {C9BCDE8B-51BA-40A6-B7A1-186F6C6B6CCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C9BCDE8B-51BA-40A6-B7A1-186F6C6B6CCE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C9BCDE8B-51BA-40A6-B7A1-186F6C6B6CCE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C9BCDE8B-51BA-40A6-B7A1-186F6C6B6CCE}.Release|Any CPU.Build.0 = Release|Any CPU - {0DFE9D18-D6B3-4097-AF87-D06B1B9DB4FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0DFE9D18-D6B3-4097-AF87-D06B1B9DB4FA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0DFE9D18-D6B3-4097-AF87-D06B1B9DB4FA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0DFE9D18-D6B3-4097-AF87-D06B1B9DB4FA}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {313B3DCB-6BC8-4578-9FCB-339E2DED8978} - EndGlobalSection -EndGlobal diff --git a/core/tutorials/using-on-mac-vs-full-solution/WordCounter/TestLibrary/TestLibrary.csproj b/core/tutorials/using-on-mac-vs-full-solution/WordCounter/TestLibrary/TestLibrary.csproj deleted file mode 100644 index 689d978c700..00000000000 --- a/core/tutorials/using-on-mac-vs-full-solution/WordCounter/TestLibrary/TestLibrary.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - netcoreapp2.2 - - - - - - - - - - - - - diff --git a/core/tutorials/using-on-mac-vs-full-solution/WordCounter/TestLibrary/TextUtilsTests.cs b/core/tutorials/using-on-mac-vs-full-solution/WordCounter/TestLibrary/TextUtilsTests.cs deleted file mode 100644 index 81ff8c1fd70..00000000000 --- a/core/tutorials/using-on-mac-vs-full-solution/WordCounter/TestLibrary/TextUtilsTests.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Xunit; -using TextUtils; -using System.Diagnostics; - -namespace TestLibrary -{ - public class TextUtils_GetWordCountShould - { - [Fact] - public void IgnoreCasing() - { - var wordCount = WordCount.GetWordCount("Jack", "Jack jack"); - - Assert.Equal(2, wordCount); - } - - [Theory] - [InlineData(0, "Ting", "Does not appear in the string.")] - [InlineData(1, "Ting", "Ting appears once.")] - [InlineData(2, "Ting", "Ting appears twice with Ting.")] - public void CountInstancesCorrectly(int count, - string searchWord, - string inputString) - { - Assert.Equal(count, WordCount.GetWordCount(searchWord, - inputString)); - } - } -} diff --git a/core/tutorials/using-on-mac-vs-full-solution/WordCounter/TextUtils/TextUtils.csproj b/core/tutorials/using-on-mac-vs-full-solution/WordCounter/TextUtils/TextUtils.csproj deleted file mode 100644 index b290d67fb72..00000000000 --- a/core/tutorials/using-on-mac-vs-full-solution/WordCounter/TextUtils/TextUtils.csproj +++ /dev/null @@ -1,7 +0,0 @@ - - - - netstandard1.4 - - - diff --git a/core/tutorials/using-on-mac-vs-full-solution/WordCounter/TextUtils/WordCount.cs b/core/tutorials/using-on-mac-vs-full-solution/WordCounter/TextUtils/WordCount.cs deleted file mode 100644 index 500ab4131d1..00000000000 --- a/core/tutorials/using-on-mac-vs-full-solution/WordCounter/TextUtils/WordCount.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Linq; - -namespace TextUtils -{ - public static class WordCount - { - public static int GetWordCount(string searchWord, string inputString) - { - // Null check these variables and determine if they have values. - if (string.IsNullOrEmpty(searchWord) || string.IsNullOrEmpty(inputString)) - { - return 0; - } - - // Convert the string into an array of words. - var source = inputString.Split(new char[] { '.', '?', '!', ' ', ';', ':', ',' }, - StringSplitOptions.RemoveEmptyEntries); - - // Create the query. Use ToLowerInvariant to match uppercase/lowercase strings. - var matchQuery = from word in source - where word.ToLowerInvariant() == searchWord.ToLowerInvariant() - select word; - - // Count the matches, which executes the query. Return the result. - return matchQuery.Count(); - } - } -} diff --git a/core/tutorials/using-on-mac-vs-full-solution/WordCounter/WordCounter.sln b/core/tutorials/using-on-mac-vs-full-solution/WordCounter/WordCounter.sln deleted file mode 100644 index 18e597218e3..00000000000 --- a/core/tutorials/using-on-mac-vs-full-solution/WordCounter/WordCounter.sln +++ /dev/null @@ -1,29 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TextUtils", "TextUtils\TextUtils.csproj", "{78838D20-B7C5-4468-835D-C300BB236AD6}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestLibrary", "TestLibrary\TestLibrary.csproj", "{0C799E9B-C539-4B0F-A768-B478AA14A631}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WordCounterApp", "WordCounterApp\WordCounterApp.csproj", "{EACA52F3-6AFC-4374-A6BC-55796804F35D}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {78838D20-B7C5-4468-835D-C300BB236AD6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {78838D20-B7C5-4468-835D-C300BB236AD6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {78838D20-B7C5-4468-835D-C300BB236AD6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {78838D20-B7C5-4468-835D-C300BB236AD6}.Release|Any CPU.Build.0 = Release|Any CPU - {0C799E9B-C539-4B0F-A768-B478AA14A631}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0C799E9B-C539-4B0F-A768-B478AA14A631}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0C799E9B-C539-4B0F-A768-B478AA14A631}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0C799E9B-C539-4B0F-A768-B478AA14A631}.Release|Any CPU.Build.0 = Release|Any CPU - {EACA52F3-6AFC-4374-A6BC-55796804F35D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EACA52F3-6AFC-4374-A6BC-55796804F35D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EACA52F3-6AFC-4374-A6BC-55796804F35D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EACA52F3-6AFC-4374-A6BC-55796804F35D}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection -EndGlobal diff --git a/core/tutorials/using-on-mac-vs-full-solution/WordCounter/WordCounterApp/Program.cs b/core/tutorials/using-on-mac-vs-full-solution/WordCounter/WordCounterApp/Program.cs deleted file mode 100644 index 8c13b3f5c52..00000000000 --- a/core/tutorials/using-on-mac-vs-full-solution/WordCounter/WordCounterApp/Program.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using TextUtils; - -namespace WordCounterApp -{ - class Program - { - static void Main(string[] args) - { - Console.WriteLine("Enter a search word:"); - var searchWord = Console.ReadLine(); - Console.WriteLine("Provide a string to search:"); - var inputString = Console.ReadLine(); - - var wordCount = WordCount.GetWordCount(searchWord, inputString); - - var pluralChar = "s"; - if (wordCount == 1) - { - pluralChar = string.Empty; - } - - Console.WriteLine($"The search word {searchWord} appears " + - $"{wordCount} time{pluralChar}."); - } - } -} diff --git a/core/tutorials/using-on-mac-vs-full-solution/WordCounter/WordCounterApp/WordCounterApp.csproj b/core/tutorials/using-on-mac-vs-full-solution/WordCounter/WordCounterApp/WordCounterApp.csproj deleted file mode 100644 index 02118320b10..00000000000 --- a/core/tutorials/using-on-mac-vs-full-solution/WordCounter/WordCounterApp/WordCounterApp.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - - Exe - netcoreapp2.2 - - - - - - - - - - diff --git a/core/tutorials/vb-library-with-visual-studio/stringlibrary.vb b/core/tutorials/vb-library-with-visual-studio/stringlibrary.vb deleted file mode 100644 index 093b85fa323..00000000000 --- a/core/tutorials/vb-library-with-visual-studio/stringlibrary.vb +++ /dev/null @@ -1,15 +0,0 @@ -Imports System.Runtime.CompilerServices - -Namespace UtilityLibraries - Public Module StringLibrary - - Public Function StartsWithUpper(str As String) As Boolean - If String.IsNullOrWhiteSpace(str) Then - Return False - End If - - Dim ch As Char = str(0) - Return Char.IsUpper(ch) - End Function - End Module -End Namespace