From f8c6d9ac901fd1993d3780cf9661a370dadb1fdd Mon Sep 17 00:00:00 2001 From: Shahin Shayandeh Date: Wed, 19 Jul 2017 12:55:43 -0700 Subject: [PATCH] Add dynamic context and bot.builder project --- .gitignore | 239 ++++++++++++++++++ Microsoft.Bot.Builder.sln | 28 ++ .../Microsoft.Bot.Builder/DynamicContext.cs | 92 +++++++ .../Microsoft.Bot.Builder.csproj | 11 + .../DynamicContextTests.cs | 53 ++++ .../Microsoft.Bot.Builder.Tests.csproj | 74 ++++++ .../Properties/AssemblyInfo.cs | 20 ++ .../packages.config | 5 + 8 files changed, 522 insertions(+) create mode 100644 .gitignore create mode 100644 Microsoft.Bot.Builder.sln create mode 100644 library/Microsoft.Bot.Builder/DynamicContext.cs create mode 100644 library/Microsoft.Bot.Builder/Microsoft.Bot.Builder.csproj create mode 100644 test/Microsoft.Bot.Builder.Tests/DynamicContextTests.cs create mode 100644 test/Microsoft.Bot.Builder.Tests/Microsoft.Bot.Builder.Tests.csproj create mode 100644 test/Microsoft.Bot.Builder.Tests/Properties/AssemblyInfo.cs create mode 100644 test/Microsoft.Bot.Builder.Tests/packages.config diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..fba4c25f3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,239 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ +ecf/ +rcf/ + +# Visual Studio 2015 cache/options directory +.vs/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +*.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +## TODO: Comment the next line if you want to checkin your +## web deploy settings but do note that will include unencrypted +## passwords +#*.pubxml + +## ignore imporeted publish xml files +*intercom-botdirectory-scratch\ -\ FTP.pubxml +*intercom-botdirectory-scratch\ -\ Web\ Deploy.pubxml + +*.publishproj + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config + +# Windows Azure Build Output +csx/ +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# LightSwitch generated files +GeneratedArtifacts/ +_Pvt_Extensions/ +ModelManifest.xml +/Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll +/Microsoft.CodeDom.Providers.DotNetCompilerPlatform.xml +/PublishScripts/Scripts/Deploy-AzureResourceGroup-5.ps1 +/PublishScripts + + + + + + + + + +# User-specific files +Documentation/Doxygen_warnings.txt + +# Build results +Documentation/docs/ + +# Azure publish profiles +*.pubxml +PublishProfiles/ diff --git a/Microsoft.Bot.Builder.sln b/Microsoft.Bot.Builder.sln new file mode 100644 index 000000000..a8e17336e --- /dev/null +++ b/Microsoft.Bot.Builder.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26430.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder", "library\Microsoft.Bot.Builder\Microsoft.Bot.Builder.csproj", "{74908F42-3842-49B4-9344-60BB791FDE32}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Bot.Builder.Tests", "test\Microsoft.Bot.Builder.Tests\Microsoft.Bot.Builder.Tests.csproj", "{07D54838-D4F7-4CA1-9EED-E5C1470D584C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {74908F42-3842-49B4-9344-60BB791FDE32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {74908F42-3842-49B4-9344-60BB791FDE32}.Debug|Any CPU.Build.0 = Debug|Any CPU + {74908F42-3842-49B4-9344-60BB791FDE32}.Release|Any CPU.ActiveCfg = Release|Any CPU + {74908F42-3842-49B4-9344-60BB791FDE32}.Release|Any CPU.Build.0 = Release|Any CPU + {07D54838-D4F7-4CA1-9EED-E5C1470D584C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {07D54838-D4F7-4CA1-9EED-E5C1470D584C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {07D54838-D4F7-4CA1-9EED-E5C1470D584C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {07D54838-D4F7-4CA1-9EED-E5C1470D584C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/library/Microsoft.Bot.Builder/DynamicContext.cs b/library/Microsoft.Bot.Builder/DynamicContext.cs new file mode 100644 index 000000000..fd315a1a3 --- /dev/null +++ b/library/Microsoft.Bot.Builder/DynamicContext.cs @@ -0,0 +1,92 @@ +using System.Collections.Generic; +using System.Dynamic; +using System.Linq; +using System.Reflection; + +namespace Microsoft.Bot.Builder +{ + public class DynamicContext : DynamicObject + { + private Dictionary dynamicProperties { get; set; } = new Dictionary(); + private string[] _objectProperties = null; + + protected string[] objectProperties + { + get + { + if (_objectProperties == null) + { + lock (dynamicProperties) + { + if (_objectProperties == null) + _objectProperties = this.GetType().GetTypeInfo().DeclaredProperties + .Where(pi => pi.Name != "Item") + .Select(pi => pi.Name) + .ToArray(); + } + } + return _objectProperties; + } + } + + public override System.Collections.Generic.IEnumerable GetDynamicMemberNames() + { + foreach (var p in this.objectProperties) + yield return p; + foreach (var key in this.dynamicProperties.Keys) + yield return key; + yield break; + } + + public override bool TryGetMember(GetMemberBinder binder, out object result) + { + return TryGetMember(binder.Name, out result); + } + + public override bool TrySetMember(SetMemberBinder binder, object value) + { + return TrySetMember(binder.Name, value); + } + + public dynamic this[string name] + { + get + { + object value; + this.TryGetMember(name, out value); + return value; + } + set { this.dynamicProperties[name] = value; } + } + + private bool TryGetMember(string name, out object result) + { + if (this.dynamicProperties.ContainsKey(name)) + { + result = this.dynamicProperties[name]; + return true; + } + else if (this.objectProperties.Contains(name)) + { + var prop = this.GetType().GetTypeInfo().GetDeclaredProperty(name); + result = prop.GetValue(this); + return true; + } + + result = null; + return false; + } + + private bool TrySetMember(string name, object value) + { + var prop = this.GetType().GetTypeInfo().GetDeclaredProperty(name); + if (prop != null) + { + prop.SetValue(this, value); + return true; + } + dynamicProperties[name] = value; + return true; + } + } +} diff --git a/library/Microsoft.Bot.Builder/Microsoft.Bot.Builder.csproj b/library/Microsoft.Bot.Builder/Microsoft.Bot.Builder.csproj new file mode 100644 index 000000000..74e21af8c --- /dev/null +++ b/library/Microsoft.Bot.Builder/Microsoft.Bot.Builder.csproj @@ -0,0 +1,11 @@ + + + + netstandard2.0 + + + + + + + \ No newline at end of file diff --git a/test/Microsoft.Bot.Builder.Tests/DynamicContextTests.cs b/test/Microsoft.Bot.Builder.Tests/DynamicContextTests.cs new file mode 100644 index 000000000..d7e97a79d --- /dev/null +++ b/test/Microsoft.Bot.Builder.Tests/DynamicContextTests.cs @@ -0,0 +1,53 @@ +using System; +using System.Dynamic; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Microsoft.Bot.Builder.Tests +{ + [TestClass] + public class DynamicContextTests + { + [TestMethod] + public void DynamicContext_DynamicProperties() + { + var testValue = "testValue"; + var context = new DynamicContext(); + context["test"] = testValue; + Assert.AreEqual(context["test"], "testValue"); + } + + class Context : DynamicContext + { + public string Name { get; set; } + } + + class TestBinder : GetMemberBinder + { + public TestBinder(string name, bool ignoreCase) : base(name, ignoreCase) + { + } + + public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion) + { + throw new NotImplementedException(); + } + } + + [TestMethod] + public void DynamicContext_AccessDeclaredProperties() + { + var testValue = "testValue"; + dynamic context = new Context(); + context.Name = testValue; + context.Test = testValue; + + Assert.AreEqual(context.Name, context.Test); + + object value; + Assert.IsTrue((context as Context).TryGetMember(new TestBinder("Name", false), out value)); + Assert.AreEqual(testValue, value as string); + } + + + } +} diff --git a/test/Microsoft.Bot.Builder.Tests/Microsoft.Bot.Builder.Tests.csproj b/test/Microsoft.Bot.Builder.Tests/Microsoft.Bot.Builder.Tests.csproj new file mode 100644 index 000000000..a3d06af2d --- /dev/null +++ b/test/Microsoft.Bot.Builder.Tests/Microsoft.Bot.Builder.Tests.csproj @@ -0,0 +1,74 @@ + + + + + Debug + AnyCPU + {07D54838-D4F7-4CA1-9EED-E5C1470D584C} + Library + Properties + Microsoft.Bot.Builder.Tests + Microsoft.Bot.Builder.Tests + v4.6.1 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + ..\..\packages\MSTest.TestFramework.1.1.11\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + + + ..\..\packages\MSTest.TestFramework.1.1.11\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + + + + + + + + + + + + + {74908f42-3842-49b4-9344-60bb791fde32} + Microsoft.Bot.Builder + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/test/Microsoft.Bot.Builder.Tests/Properties/AssemblyInfo.cs b/test/Microsoft.Bot.Builder.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..dc62117d6 --- /dev/null +++ b/test/Microsoft.Bot.Builder.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,20 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Microsoft.Bot.Builder.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Microsoft.Bot.Builder.Tests")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +[assembly: Guid("07d54838-d4f7-4ca1-9eed-e5c1470d584c")] + +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/test/Microsoft.Bot.Builder.Tests/packages.config b/test/Microsoft.Bot.Builder.Tests/packages.config new file mode 100644 index 000000000..178e0f975 --- /dev/null +++ b/test/Microsoft.Bot.Builder.Tests/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file