diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f5e7024..0f3eb0a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,7 +5,6 @@ on: branches: - main pull_request: - types: [closed] branches: - main diff --git a/Directory.Build.props b/Directory.Build.props index 3a9d663..b736c47 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,12 +1,10 @@ 2.12 - true MyCSharp.de, Benjamin Abt, Günther Foidl and Contributors https://github.com/mycsharp/HttpUserAgentParser MIT en-US - $(MSBuildProjectName.Contains('Test')) HTTP User Agent Parser for .NET true preview @@ -14,5 +12,12 @@ true true embedded + $(MSBuildProjectName.Contains('Test')) + $(MsBuildProjectName.Contains('Benchmark')) + false + + + + true diff --git a/perf/MyCSharp.HttpUserAgentParser.Benchmarks/ExternalCode/UserAgentServiceUserAgent.cs b/perf/MyCSharp.HttpUserAgentParser.Benchmarks/ExternalCode/UserAgentServiceUserAgent.cs deleted file mode 100644 index 661a3e8..0000000 --- a/perf/MyCSharp.HttpUserAgentParser.Benchmarks/ExternalCode/UserAgentServiceUserAgent.cs +++ /dev/null @@ -1,334 +0,0 @@ -// Copyright © myCSharp 2020-2021, all rights reserved - -using System; -using System.Collections.Generic; -using System.Text.RegularExpressions; - -namespace MyCSharp.HttpUserAgentParser.Benchmarks.ExternalCode -{ - /// - /// from https://raw.githubusercontent.com/DannyBoyNg/UserAgentService/master/UserAgentService/UserAgent.cs - /// as copy because ctor is internal - /// - internal class UserAgentServiceUserAgent - { - internal static Dictionary platforms = new() - { - { "windows nt 10.0", "Windows 10" }, - { "windows nt 6.3", "Windows 8.1" }, - { "windows nt 6.2", "Windows 8" }, - { "windows nt 6.1", "Windows 7" }, - { "windows nt 6.0", "Windows Vista" }, - { "windows nt 5.2", "Windows 2003" }, - { "windows nt 5.1", "Windows XP" }, - { "windows nt 5.0", "Windows 2000" }, - { "windows nt 4.0", "Windows NT 4.0" }, - { "winnt4.0", "Windows NT 4.0" }, - { "winnt 4.0", "Windows NT" }, - { "winnt", "Windows NT" }, - { "windows 98", "Windows 98" }, - { "win98", "Windows 98" }, - { "windows 95", "Windows 95" }, - { "win95", "Windows 95" }, - { "windows phone", "Windows Phone" }, - { "windows", "Unknown Windows OS" }, - { "android", "Android" }, - { "blackberry", "BlackBerry" }, - { "iphone", "iOS" }, - { "ipad", "iOS" }, - { "ipod", "iOS" }, - { "os x", "Mac OS X" }, - { "ppc mac", "Power PC Mac" }, - { "freebsd", "FreeBSD" }, - { "ppc", "Macintosh" }, - { "linux", "Linux" }, - { "debian", "Debian" }, - { "sunos", "Sun Solaris" }, - { "beos", "BeOS" }, - { "apachebench", "ApacheBench" }, - { "aix", "AIX" }, - { "irix", "Irix" }, - { "osf", "DEC OSF" }, - { "hp-ux", "HP-UX" }, - { "netbsd", "NetBSD" }, - { "bsdi", "BSDi" }, - { "openbsd", "OpenBSD" }, - { "gnu", "GNU/Linux" }, - { "unix", "Unknown Unix OS" }, - { "symbian", "Symbian OS" }, - }; - - internal static Dictionary browsers = new() - { - { "OPR", "Opera" }, - { "Flock", "Flock" }, - { "Edge", "Edge" }, - { "Edg", "Edge" }, - { "Chrome", "Chrome" }, - { "Opera.*?Version", "Opera" }, - { "Opera", "Opera" }, - { "MSIE", "Internet Explorer" }, - { "Internet Explorer", "Internet Explorer" }, - { "Trident.* rv", "Internet Explorer" }, - { "Shiira", "Shiira" }, - { "Firefox", "Firefox" }, - { "Chimera", "Chimera" }, - { "Phoenix", "Phoenix" }, - { "Firebird", "Firebird" }, - { "Camino", "Camino" }, - { "Netscape", "Netscape" }, - { "OmniWeb", "OmniWeb" }, - { "Safari", "Safari" }, - { "Mozilla", "Mozilla" }, - { "Konqueror", "Konqueror" }, - { "icab", "iCab" }, - { "Lynx", "Lynx" }, - { "Links", "Links" }, - { "hotjava", "HotJava" }, - { "amaya", "Amaya" }, - { "IBrowse", "IBrowse" }, - { "Maxthon", "Maxthon" }, - { "Ubuntu", "Ubuntu Web Browser" }, - { "Vivaldi", "Vivaldi" }, - }; - - internal static Dictionary mobiles = new() - { - // Legacy - { "mobileexplorer", "Mobile Explorer" }, - { "palmsource", "Palm" }, - { "palmscape", "Palmscape" }, - // Phones and Manufacturers - { "motorola", "Motorola" }, - { "nokia", "Nokia" }, - { "palm", "Palm" }, - { "iphone", "Apple iPhone" }, - { "ipad", "iPad" }, - { "ipod", "Apple iPod Touch" }, - { "sony", "Sony Ericsson" }, - { "ericsson", "Sony Ericsson" }, - { "blackberry", "BlackBerry" }, - { "cocoon", "O2 Cocoon" }, - { "blazer", "Treo" }, - { "lg", "LG" }, - { "amoi", "Amoi" }, - { "xda", "XDA" }, - { "mda", "MDA" }, - { "vario", "Vario" }, - { "htc", "HTC" }, - { "samsung", "Samsung" }, - { "sharp", "Sharp" }, - { "sie-", "Siemens" }, - { "alcatel", "Alcatel" }, - { "benq", "BenQ" }, - { "ipaq", "HP iPaq" }, - { "mot-", "Motorola" }, - { "playstation portable", "PlayStation Portable" }, - { "playstation 3", "PlayStation 3" }, - { "playstation vita", "PlayStation Vita" }, - { "hiptop", "Danger Hiptop" }, - { "nec-", "NEC" }, - { "panasonic", "Panasonic" }, - { "philips", "Philips" }, - { "sagem", "Sagem" }, - { "sanyo", "Sanyo" }, - { "spv", "SPV" }, - { "zte", "ZTE" }, - { "sendo", "Sendo" }, - { "nintendo dsi", "Nintendo DSi" }, - { "nintendo ds", "Nintendo DS" }, - { "nintendo 3ds", "Nintendo 3DS" }, - { "wii", "Nintendo Wii" }, - { "open web", "Open Web" }, - { "openweb", "OpenWeb" }, - // Operating Systems - { "android", "Android" }, - { "symbian", "Symbian" }, - { "SymbianOS", "SymbianOS" }, - { "elaine", "Palm" }, - { "series60", "Symbian S60" }, - { "windows ce", "Windows CE" }, - // Browsers - { "obigo", "Obigo" }, - { "netfront", "Netfront Browser" }, - { "openwave", "Openwave Browser" }, - { "mobilexplorer", "Mobile Explorer" }, - { "operamini", "Opera Mini" }, - { "opera mini", "Opera Mini" }, - { "opera mobi", "Opera Mobile" }, - { "fennec", "Firefox Mobile" }, - // Other - { "digital paths", "Digital Paths" }, - { "avantgo", "AvantGo" }, - { "xiino", "Xiino" }, - { "novarra", "Novarra Transcoder" }, - { "vodafone", "Vodafone" }, - { "docomo", "NTT DoCoMo" }, - { "o2", "O2" }, - // Fallback - { "mobile", "Generic Mobile" }, - { "wireless", "Generic Mobile" }, - { "j2me", "Generic Mobile" }, - { "midp", "Generic Mobile" }, - { "cldc", "Generic Mobile" }, - { "up.link", "Generic Mobile" }, - { "up.browser", "Generic Mobile" }, - { "smartphone", "Generic Mobile" }, - { "cellphone", "Generic Mobile" }, - }; - - internal static Dictionary robots = new() - { - { "googlebot", "Googlebot" }, - { "msnbot", "MSNBot" }, - { "baiduspider", "Baiduspider" }, - { "bingbot", "Bing" }, - { "slurp", "Inktomi Slurp" }, - { "yahoo", "Yahoo" }, - { "ask jeeves", "Ask Jeeves" }, - { "fastcrawler", "FastCrawler" }, - { "infoseek", "InfoSeek Robot 1.0" }, - { "lycos", "Lycos" }, - { "yandex", "YandexBot" }, - { "mediapartners-google", "MediaPartners Google" }, - { "CRAZYWEBCRAWLER", "Crazy Webcrawler" }, - { "adsbot-google", "AdsBot Google" }, - { "feedfetcher-google", "Feedfetcher Google" }, - { "curious george", "Curious George" }, - { "ia_archiver", "Alexa Crawler" }, - { "MJ12bot", "Majestic-12" }, - { "Uptimebot", "Uptimebot" }, - }; - - internal string Agent = ""; - - /// - /// Gets or sets a value indicating whether this UserAgent is a browser. - /// - /// - /// true if this UserAgent is a browser; otherwise, false. - /// - public bool IsBrowser { get; set; } = false; - /// - /// Gets or sets a value indicating whether this UserAgent is a robot. - /// - /// - /// true if this UserAgent is a robot; otherwise, false. - /// - public bool IsRobot { get; set; } = false; - /// - /// Gets or sets a value indicating whether this UserAgent is a mobile device. - /// - /// - /// true if this UserAgent is a mobile device; otherwise, false. - /// - public bool IsMobile { get; set; } = false; - /// - /// Gets or sets the platform. - /// - /// - /// The platform or operating system. - /// - public string Platform { get; set; } = ""; - /// - /// Gets or sets the browser. - /// - /// - /// The browser. - /// - public string Browser { get; set; } = ""; - /// - /// Gets or sets the browser version. - /// - /// - /// The browser version. - /// - public string BrowserVersion { get; set; } = ""; - /// - /// Gets or sets the mobile device. - /// - /// - /// The mobile device. - /// - public string Mobile { get; set; } = ""; - /// - /// Gets or sets the robot. - /// - /// - /// The robot. - /// - public string Robot { get; set; } = ""; - - internal UserAgentServiceUserAgent(string? userAgentString = null) - { - if (userAgentString != null) - { - Agent = userAgentString.Trim(); - this.SetPlatform(); - if (this.SetRobot()) return; - if (this.SetBrowser()) return; - if (this.SetMobile()) return; - } - } - - internal bool SetPlatform() - { - foreach (var item in platforms) - { - if (Regex.IsMatch(Agent, $"{Regex.Escape(item.Key)}", RegexOptions.IgnoreCase)) - { - this.Platform = item.Value; - return true; - } - } - this.Platform = "Unknown Platform"; - return false; - } - - internal bool SetBrowser() - { - foreach (var item in browsers) - { - var match = Regex.Match(Agent, $@"{item.Key}.*?([0-9\.]+)", RegexOptions.IgnoreCase); - if (match.Success) - { - this.IsBrowser = true; - this.BrowserVersion = match.Groups[1].Value; - this.Browser = item.Value; - this.SetMobile(); - return true; - } - } - return false; - } - - internal bool SetRobot() - { - foreach (var item in robots) - { - if (Regex.IsMatch(Agent, $"{Regex.Escape(item.Key)}", RegexOptions.IgnoreCase)) - { - this.IsRobot = true; - this.Robot = item.Value; - this.SetMobile(); - return true; - } - } - return false; - } - - internal bool SetMobile() - { - foreach (var item in mobiles) - { - if (Agent?.IndexOf(item.Key, StringComparison.OrdinalIgnoreCase) != -1) - { - this.IsMobile = true; - this.Mobile = item.Value; - return true; - } - } - return false; - } - } -} diff --git a/perf/MyCSharp.HttpUserAgentParser.Benchmarks/HttpUserAgentParserBenchmarks.cs b/perf/MyCSharp.HttpUserAgentParser.Benchmarks/HttpUserAgentParserBenchmarks.cs new file mode 100644 index 0000000..3b90e5b --- /dev/null +++ b/perf/MyCSharp.HttpUserAgentParser.Benchmarks/HttpUserAgentParserBenchmarks.cs @@ -0,0 +1,49 @@ +// Copyright © myCSharp 2020-2021, all rights reserved + +using System.Collections.Generic; +using System.Linq; +using BenchmarkDotNet.Attributes; + +#if OS_WIN +using BenchmarkDotNet.Diagnostics.Windows.Configs; +#endif + +namespace MyCSharp.HttpUserAgentParser.Benchmarks +{ + [MemoryDiagnoser] +#if OS_WIN + [EtwProfiler] // needs admin-rights +#endif + public class HttpUserAgentParserBenchmarks + { + private string[] _testUserAgentMix; + private HttpUserAgentInformation[] _results; + + [GlobalSetup] + public void GlobalSetup() + { + _testUserAgentMix = GetTestUserAgents().ToArray(); + _results = new HttpUserAgentInformation[_testUserAgentMix.Length]; + } + + private static IEnumerable GetTestUserAgents() + { + yield return "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36"; + yield return "APIs-Google (+https://developers.google.com/webmasters/APIs-Google.html)"; + yield return "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0"; + yield return "yeah I'm unknown user agent, just to bring some fun to the mix"; + } + + [Benchmark] + public void Parse() + { + string[] testUserAgentMix = _testUserAgentMix; + HttpUserAgentInformation[] results = _results; + + for (int i = 0; i < testUserAgentMix.Length; ++i) + { + results[i] = HttpUserAgentParser.Parse(testUserAgentMix[i]); + } + } + } +} diff --git a/perf/MyCSharp.HttpUserAgentParser.Benchmarks/LibraryComparison/LibraryComparisonBenchmarks.cs b/perf/MyCSharp.HttpUserAgentParser.Benchmarks/LibraryComparison/LibraryComparisonBenchmarks.cs new file mode 100644 index 0000000..9df2806 --- /dev/null +++ b/perf/MyCSharp.HttpUserAgentParser.Benchmarks/LibraryComparison/LibraryComparisonBenchmarks.cs @@ -0,0 +1,87 @@ +// Copyright © myCSharp 2020-2021, all rights reserved + +using System.Collections.Generic; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Columns; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Diagnosers; +using DeviceDetectorNET; +using MyCSharp.HttpUserAgentParser.Providers; + +namespace MyCSharp.HttpUserAgentParser.Benchmarks.LibraryComparison +{ + [ShortRunJob] + [MemoryDiagnoser] + [CategoriesColumn] + [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] + public class LibraryComparisonBenchmarks + { + public record TestData(string Label, string UserAgent) + { + public override string ToString() => Label; + } + + [ParamsSource(nameof(GetTestUserAgents))] + public TestData Data { get; set; } + + public IEnumerable GetTestUserAgents() + { + yield return new("Chrome Win10", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36"); + yield return new("Google-Bot", "APIs-Google (+https://developers.google.com/webmasters/APIs-Google.html)"); + } + + [Benchmark(Baseline = true, Description = "MyCSharp")] + [BenchmarkCategory("Basic")] + public HttpUserAgentInformation MyCSharpBasic() + { + HttpUserAgentInformation info = HttpUserAgentParser.Parse(Data.UserAgent); + return info; + } + + private static readonly HttpUserAgentParserCachedProvider s_myCSharpCachedProvider = new(); + + [Benchmark(Baseline = true, Description = "MyCSharp")] + [BenchmarkCategory("Cached")] + public HttpUserAgentInformation MyCSharpCached() + { + return s_myCSharpCachedProvider.Parse(Data.UserAgent); + } + + [Benchmark(Description = "UAParser")] + [BenchmarkCategory("Basic")] + public UAParser.ClientInfo UAParserBasic() + { + UAParser.ClientInfo info = UAParser.Parser.GetDefault().Parse(Data.UserAgent); + return info; + } + + private static readonly UAParser.Parser s_uaParser = UAParser.Parser.GetDefault(new UAParser.ParserOptions { UseCompiledRegex = true }); + + [Benchmark(Description = "UAParser")] + [BenchmarkCategory("Cached")] + public UAParser.ClientInfo UAParserCached() + { + UAParser.ClientInfo info = s_uaParser.Parse(Data.UserAgent); + return info; + } + + [Benchmark(Description = "DeviceDetector.NET")] + [BenchmarkCategory("Basic")] + public object DeviceDetectorNETBasic() + { + DeviceDetector dd = new(Data.UserAgent); + dd.Parse(); + + var info = new + { + Client = dd.GetClient(), + OS = dd.GetOs(), + Device = dd.GetDeviceName(), + Brand = dd.GetBrandName(), + Model = dd.GetModel() + }; + + return info; + } + } +} diff --git a/perf/MyCSharp.HttpUserAgentParser.Benchmarks/MyCSharp.HttpUserAgentParser.Benchmarks.csproj b/perf/MyCSharp.HttpUserAgentParser.Benchmarks/MyCSharp.HttpUserAgentParser.Benchmarks.csproj index bbfef02..bfe6d06 100644 --- a/perf/MyCSharp.HttpUserAgentParser.Benchmarks/MyCSharp.HttpUserAgentParser.Benchmarks.csproj +++ b/perf/MyCSharp.HttpUserAgentParser.Benchmarks/MyCSharp.HttpUserAgentParser.Benchmarks.csproj @@ -3,19 +3,26 @@ Exe net5.0 - true - 9.0 - full - true + disable + + + + $(DefineConstants);OS_WIN - + + + + + + + diff --git a/perf/MyCSharp.HttpUserAgentParser.Benchmarks/Program.cs b/perf/MyCSharp.HttpUserAgentParser.Benchmarks/Program.cs index 743334c..d4e2a76 100644 --- a/perf/MyCSharp.HttpUserAgentParser.Benchmarks/Program.cs +++ b/perf/MyCSharp.HttpUserAgentParser.Benchmarks/Program.cs @@ -1,14 +1,12 @@ // Copyright © myCSharp 2020-2021, all rights reserved +using System.Reflection; +using BenchmarkDotNet.Configs; using BenchmarkDotNet.Running; -namespace MyCSharp.HttpUserAgentParser.Benchmarks -{ - class Program - { - static void Main() - { - BenchmarkRunner.Run(); - } - } -} +// Needed for DeviceDetector.NET +// https://github.com/totpero/DeviceDetector.NET/issues/44 +ManualConfig config = ManualConfig.Create(DefaultConfig.Instance) + .WithOptions(ConfigOptions.DisableOptimizationsValidator); + +BenchmarkSwitcher.FromAssembly(Assembly.GetExecutingAssembly()).Run(args, config); diff --git a/perf/MyCSharp.HttpUserAgentParser.Benchmarks/UserAgentBenchmarks.cs b/perf/MyCSharp.HttpUserAgentParser.Benchmarks/UserAgentBenchmarks.cs deleted file mode 100644 index 76a77bd..0000000 --- a/perf/MyCSharp.HttpUserAgentParser.Benchmarks/UserAgentBenchmarks.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright © myCSharp 2020-2021, all rights reserved - -using System.Collections.Generic; -using System.Linq; -using BenchmarkDotNet.Attributes; -using MyCSharp.HttpUserAgentParser.Benchmarks.ExternalCode; -using UAParser; - -namespace MyCSharp.HttpUserAgentParser.Benchmarks -{ - [MemoryDiagnoser] -#if OS_WIN - [EtwProfiler] // needs admin-rights -#endif - public class UserAgentBenchmarks - { - private Parser _uaParser; - - private string[] _testUserAgentMix; - - private static IEnumerable GetTestUserAgents() - { - yield return - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36"; - yield return "APIs-Google (+https://developers.google.com/webmasters/APIs-Google.html)"; - yield return "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0"; - yield return "yeah I'm unknown user agent, just to bring some fun to the mix"; - } - - [GlobalSetup] - public void Setup() - { - _uaParser = UAParser.Parser.GetDefault(new ParserOptions()); - _testUserAgentMix = GetTestUserAgents().ToArray(); - } - - [Benchmark(Description = "UA Parser")] - public void UAParserTest() - { - string[] testUserAgentMix = _testUserAgentMix; - - for (int i = 0; i < testUserAgentMix.Length; ++i) - { - _uaParser.Parse(testUserAgentMix[i]); - } - } - - [Benchmark(Description = "UserAgentService")] - public void UserAgentServiceTest() - { - string[] testUserAgentMix = _testUserAgentMix; - - for (int i = 0; i < testUserAgentMix.Length; ++i) - { - new UserAgentServiceUserAgent(testUserAgentMix[i]); - } - } - - [Benchmark(Description = "HttpUserAgentParser")] - public void HttpUserAgentParserTest() - { - string[] testUserAgentMix = _testUserAgentMix; - - for (int i = 0; i < testUserAgentMix.Length; ++i) - { - HttpUserAgentParser.Parse(testUserAgentMix[i]); - } - } - } -} diff --git a/src/MyCSharp.HttpUserAgentParser.AspNetCore/MyCSharp.HttpUserAgentParser.AspNetCore.csproj b/src/MyCSharp.HttpUserAgentParser.AspNetCore/MyCSharp.HttpUserAgentParser.AspNetCore.csproj index 241883a..f122bc5 100644 --- a/src/MyCSharp.HttpUserAgentParser.AspNetCore/MyCSharp.HttpUserAgentParser.AspNetCore.csproj +++ b/src/MyCSharp.HttpUserAgentParser.AspNetCore/MyCSharp.HttpUserAgentParser.AspNetCore.csproj @@ -4,6 +4,7 @@ HTTP User Agent Parser Extensions for ASP.NET Core HTTP User Agent Parser Extensions for ASP.NET Core net5.0 + true @@ -14,4 +15,4 @@ - \ No newline at end of file + diff --git a/src/MyCSharp.HttpUserAgentParser.MemoryCache/HttpUserAgentParserMemoryCachedProvider.cs b/src/MyCSharp.HttpUserAgentParser.MemoryCache/HttpUserAgentParserMemoryCachedProvider.cs index f618c5f..cb542f4 100644 --- a/src/MyCSharp.HttpUserAgentParser.MemoryCache/HttpUserAgentParserMemoryCachedProvider.cs +++ b/src/MyCSharp.HttpUserAgentParser.MemoryCache/HttpUserAgentParserMemoryCachedProvider.cs @@ -6,6 +6,7 @@ namespace MyCSharp.HttpUserAgentParser.MemoryCache { + /// public class HttpUserAgentParserMemoryCachedProvider : IHttpUserAgentParserProvider { private readonly IMemoryCache _memoryCache; @@ -17,6 +18,7 @@ public HttpUserAgentParserMemoryCachedProvider(IMemoryCache memoryCache, HttpUse _options = options; } + /// public HttpUserAgentInformation Parse(string userAgent) { CacheKey key = this.GetKey(userAgent); diff --git a/src/MyCSharp.HttpUserAgentParser.MemoryCache/MyCSharp.HttpUserAgentParser.MemoryCache.csproj b/src/MyCSharp.HttpUserAgentParser.MemoryCache/MyCSharp.HttpUserAgentParser.MemoryCache.csproj index 161ab49..dd632d6 100644 --- a/src/MyCSharp.HttpUserAgentParser.MemoryCache/MyCSharp.HttpUserAgentParser.MemoryCache.csproj +++ b/src/MyCSharp.HttpUserAgentParser.MemoryCache/MyCSharp.HttpUserAgentParser.MemoryCache.csproj @@ -4,6 +4,7 @@ HTTP User Agent Parser Extensions for IMemoryCache HTTP User Agent Parser Extensions for IMemoryCache netstandard2.1 + true @@ -15,4 +16,4 @@ - \ No newline at end of file + diff --git a/src/MyCSharp.HttpUserAgentParser/MyCSharp.HttpUserAgentParser.csproj b/src/MyCSharp.HttpUserAgentParser/MyCSharp.HttpUserAgentParser.csproj index dd386d8..2aabcf0 100644 --- a/src/MyCSharp.HttpUserAgentParser/MyCSharp.HttpUserAgentParser.csproj +++ b/src/MyCSharp.HttpUserAgentParser/MyCSharp.HttpUserAgentParser.csproj @@ -4,10 +4,11 @@ HTTP User Agent Parser Parses user agents for Browser, Platform and Bots. netstandard2.1 + true - \ No newline at end of file + diff --git a/src/MyCSharp.HttpUserAgentParser/Providers/IHttpUserAgentParserProvider.cs b/src/MyCSharp.HttpUserAgentParser/Providers/IHttpUserAgentParserProvider.cs index f0eb9a9..73feab1 100644 --- a/src/MyCSharp.HttpUserAgentParser/Providers/IHttpUserAgentParserProvider.cs +++ b/src/MyCSharp.HttpUserAgentParser/Providers/IHttpUserAgentParserProvider.cs @@ -1,9 +1,17 @@ -// Copyright © myCSharp 2020-2021, all rights reserved +// Copyright © myCSharp 2020-2021, all rights reserved namespace MyCSharp.HttpUserAgentParser.Providers { + /// + /// Provides the basic parsing of user agent strings. + /// public interface IHttpUserAgentParserProvider { + /// + /// Parsed the -string. + /// + /// The user agent to parse. + /// The parsed user agent information HttpUserAgentInformation Parse(string userAgent); } -} \ No newline at end of file +} diff --git a/tests/MyCSharp.HttpUserAgentParser.AspNetCore.UnitTests/MyCSharp.HttpUserAgentParser.AspNetCore.UnitTests.csproj b/tests/MyCSharp.HttpUserAgentParser.AspNetCore.UnitTests/MyCSharp.HttpUserAgentParser.AspNetCore.UnitTests.csproj index 3edaabe..5d423cd 100644 --- a/tests/MyCSharp.HttpUserAgentParser.AspNetCore.UnitTests/MyCSharp.HttpUserAgentParser.AspNetCore.UnitTests.csproj +++ b/tests/MyCSharp.HttpUserAgentParser.AspNetCore.UnitTests/MyCSharp.HttpUserAgentParser.AspNetCore.UnitTests.csproj @@ -25,4 +25,4 @@ - \ No newline at end of file + diff --git a/tests/MyCSharp.HttpUserAgentParser.MemoryCache.UnitTests/MyCSharp.HttpUserAgentParser.MemoryCache.UnitTests.csproj b/tests/MyCSharp.HttpUserAgentParser.MemoryCache.UnitTests/MyCSharp.HttpUserAgentParser.MemoryCache.UnitTests.csproj index 75ba3b0..694e361 100644 --- a/tests/MyCSharp.HttpUserAgentParser.MemoryCache.UnitTests/MyCSharp.HttpUserAgentParser.MemoryCache.UnitTests.csproj +++ b/tests/MyCSharp.HttpUserAgentParser.MemoryCache.UnitTests/MyCSharp.HttpUserAgentParser.MemoryCache.UnitTests.csproj @@ -26,4 +26,4 @@ - \ No newline at end of file + diff --git a/tests/MyCSharp.HttpUserAgentParser.UnitTests/MyCSharp.HttpUserAgentParser.UnitTests.csproj b/tests/MyCSharp.HttpUserAgentParser.UnitTests/MyCSharp.HttpUserAgentParser.UnitTests.csproj index 790d6e9..414fa69 100644 --- a/tests/MyCSharp.HttpUserAgentParser.UnitTests/MyCSharp.HttpUserAgentParser.UnitTests.csproj +++ b/tests/MyCSharp.HttpUserAgentParser.UnitTests/MyCSharp.HttpUserAgentParser.UnitTests.csproj @@ -25,4 +25,4 @@ - \ No newline at end of file +