diff --git a/DeviceId.sln b/DeviceId.sln index c23a503..60fbba2 100644 --- a/DeviceId.sln +++ b/DeviceId.sln @@ -24,7 +24,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DeviceId.Mac", "src\DeviceI EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DeviceId.Tests", "test\DeviceId.Tests\DeviceId.Tests.csproj", "{C706C3B5-4912-41E6-9EF3-B8560464680A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceId.SqlServer", "src\DeviceId.SqlServer\DeviceId.SqlServer.csproj", "{678F5EAE-C13E-4EEC-A2F3-17F43CE099FE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DeviceId.SqlServer", "src\DeviceId.SqlServer\DeviceId.SqlServer.csproj", "{678F5EAE-C13E-4EEC-A2F3-17F43CE099FE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DeviceId.Xamarin", "src\DeviceId.Xamarin\DeviceId.Xamarin.csproj", "{114925F8-6BF9-445B-A3A4-BADAD99A3EAB}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -64,6 +66,10 @@ Global {678F5EAE-C13E-4EEC-A2F3-17F43CE099FE}.Debug|Any CPU.Build.0 = Debug|Any CPU {678F5EAE-C13E-4EEC-A2F3-17F43CE099FE}.Release|Any CPU.ActiveCfg = Release|Any CPU {678F5EAE-C13E-4EEC-A2F3-17F43CE099FE}.Release|Any CPU.Build.0 = Release|Any CPU + {114925F8-6BF9-445B-A3A4-BADAD99A3EAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {114925F8-6BF9-445B-A3A4-BADAD99A3EAB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {114925F8-6BF9-445B-A3A4-BADAD99A3EAB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {114925F8-6BF9-445B-A3A4-BADAD99A3EAB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -77,6 +83,7 @@ Global {865D5271-A21F-4F4B-8F57-7278FEC051AA} = {BD122A91-437F-497E-80F1-F21BAD62C51F} {C706C3B5-4912-41E6-9EF3-B8560464680A} = {5D030E54-9156-468B-9288-498DE74D8C61} {678F5EAE-C13E-4EEC-A2F3-17F43CE099FE} = {BD122A91-437F-497E-80F1-F21BAD62C51F} + {114925F8-6BF9-445B-A3A4-BADAD99A3EAB} = {BD122A91-437F-497E-80F1-F21BAD62C51F} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {702DF5F2-A40A-46BC-A155-7CEAF7F7AA93} diff --git a/src/DeviceId.Xamarin/DeviceId.Xamarin.csproj b/src/DeviceId.Xamarin/DeviceId.Xamarin.csproj new file mode 100644 index 0000000..360cf3c --- /dev/null +++ b/src/DeviceId.Xamarin/DeviceId.Xamarin.csproj @@ -0,0 +1,25 @@ + + + + DeviceId.Xamarin + DeviceId (Xamarin) + Provides Xamarin-specific components for the DeviceId package. + 6.2.0 + + + + netstandard2.0;net5.0;net6.0 + latest + true + + + + + + + + + + + + diff --git a/src/DeviceId.Xamarin/DeviceIdBuilderExtensions.cs b/src/DeviceId.Xamarin/DeviceIdBuilderExtensions.cs new file mode 100644 index 0000000..14fa331 --- /dev/null +++ b/src/DeviceId.Xamarin/DeviceIdBuilderExtensions.cs @@ -0,0 +1,26 @@ +using System; + +namespace DeviceId; + +/// +/// Extension methods for . +/// +public static class DeviceIdBuilderExtensions +{ + /// + /// Adds Xamarin-specific components to the device ID. + /// + /// The device ID builder to add the components to. + /// An action that adds the Xamarin-specific components. + /// The device ID builder. + public static DeviceIdBuilder OnLinux(this DeviceIdBuilder builder, Action xamarinBuilderConfiguration) + { + if (xamarinBuilderConfiguration is not null) + { + var linuxBuilder = new XamarinDeviceIdBuilder(builder); + xamarinBuilderConfiguration.Invoke(linuxBuilder); + } + + return builder; + } +} diff --git a/src/DeviceId.Xamarin/XamarinDeviceIdBuilder.cs b/src/DeviceId.Xamarin/XamarinDeviceIdBuilder.cs new file mode 100644 index 0000000..97a7ec0 --- /dev/null +++ b/src/DeviceId.Xamarin/XamarinDeviceIdBuilder.cs @@ -0,0 +1,40 @@ +using System; +using System.Runtime.InteropServices; +using DeviceId.Internal; +using Xamarin.Essentials; + +namespace DeviceId; + +/// +/// Provides a fluent interface for adding Xamarin-specific components to a device identifier. +/// +public class XamarinDeviceIdBuilder +{ + /// + /// The base device identifier builder. + /// + private readonly DeviceIdBuilder _baseBuilder; + + /// + /// Initializes a new instance of the class. + /// + /// The base device identifier builder. + public XamarinDeviceIdBuilder(DeviceIdBuilder baseBuilder) + { + _baseBuilder = baseBuilder ?? throw new ArgumentNullException(nameof(baseBuilder)); + } + + /// + /// Adds a component to the device identifier. + /// If a component with the specified name already exists, it will be replaced with this newly added component. + /// + /// The component name. + /// The component to add. + /// The builder instance. + public XamarinDeviceIdBuilder AddComponent(string name, IDeviceIdComponent component) + { + _baseBuilder.AddComponent(name, component); + + return this; + } +} diff --git a/src/DeviceId.Xamarin/XamarinDeviceIdBuilderExtensions.cs b/src/DeviceId.Xamarin/XamarinDeviceIdBuilderExtensions.cs new file mode 100644 index 0000000..511ad0c --- /dev/null +++ b/src/DeviceId.Xamarin/XamarinDeviceIdBuilderExtensions.cs @@ -0,0 +1,103 @@ +using System; +using DeviceId.Components; +using Xamarin.Essentials; + +namespace DeviceId; + +/// +/// Extension methods for . +/// +public static class XamarinDeviceIdBuilderExtensions +{ + /// + /// Adds the device manufacturer to the device identifier. + /// + /// The to add the component to. + /// The instance. + public static XamarinDeviceIdBuilder AddManufacturer(this XamarinDeviceIdBuilder builder) + { + return builder.AddComponent("Manufacturer", new TextComponent(DeviceInfo.Manufacturer)); + } + + /// + /// Adds the OS-version to the device identifier. + /// + /// The to add the component to. + /// The instance. + public static XamarinDeviceIdBuilder AddOsVersion(this XamarinDeviceIdBuilder builder) + { + return builder.AddComponent("OSVersion", new TextComponent(DeviceInfo.VersionString)); + } + + /// + /// Adds the device model to the device identifier. + /// + /// The to add the component to. + /// The instance. + public static XamarinDeviceIdBuilder AddModel(this XamarinDeviceIdBuilder builder) + { + return builder.AddComponent("Model", new TextComponent(DeviceInfo.Model)); + } + + /// + /// Adds the device-platform to the device identifier. + /// + /// The to add the component to. + /// The instance. + public static XamarinDeviceIdBuilder AddPlatform(this XamarinDeviceIdBuilder builder) + { + return builder.AddComponent("Platform", new TextComponent(DeviceInfo.Platform.ToString())); + } + + /// + /// Adds the device type (physical/virtual) to the device identifier. + /// + /// The to add the component to. + /// The instance. + public static XamarinDeviceIdBuilder AddDeviceType(this XamarinDeviceIdBuilder builder) + { + return builder.AddComponent("DeviceType", new TextComponent(DeviceInfo.DeviceType.ToString())); + } + + /// + /// Adds the device idiom to the device identifier (phone, tablet, watch , ...). + /// + /// The to add the component to. + /// The instance. + public static XamarinDeviceIdBuilder AddIdiom(this XamarinDeviceIdBuilder builder) + { + return builder.AddComponent("Idiom", new TextComponent(DeviceInfo.Idiom.ToString())); + } + + /// + /// Adds the device name to the device identifier. + /// + /// The to add the component to. + /// The instance. + public static XamarinDeviceIdBuilder AddDeviceName(this XamarinDeviceIdBuilder builder) + { + return builder.AddComponent("DeviceName", new TextComponent(DeviceInfo.Name)); + } + + /// + /// Adds a generated guid to the device identifier. The generated value is persistantly stored. + /// + /// The to add the component to. + /// The instance. + public static XamarinDeviceIdBuilder AddGeneratedGuid(this XamarinDeviceIdBuilder builder) + { + const string key = "XamarinDeviceIdBuilder.GeneratedId"; + Func func = () => + { + string guid = Preferences.Get(key, ""); + if (string.IsNullOrEmpty(guid)) + { + guid = Guid.NewGuid().ToString(); + Preferences.Set(key, guid); + } + return guid; + }; + return builder.AddComponent("GeneratedGuid", new FuncComponent(func)); + } + +} diff --git a/src/DeviceId.Xamarin/_InternalsVisibleTo.cs b/src/DeviceId.Xamarin/_InternalsVisibleTo.cs new file mode 100644 index 0000000..8f018f5 --- /dev/null +++ b/src/DeviceId.Xamarin/_InternalsVisibleTo.cs @@ -0,0 +1,4 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] +[assembly: InternalsVisibleTo("DeviceId.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001008906d2e5a92d72693cfdd24b29f9c3ea5ca51972be746724afef8a65000a1ebbc88aee54e4c9c3bef49c0e837702170e99919a8b8075cfd6ed8494c5f9cd1a640a57cc907a84861bfe7ecb877d475a94ec333c6c0a586b6f37a15e67431381cac046217c0fa570c3e8e140e733254686213b77ae53fccdc1f5b3ab806ac692c1")] diff --git a/src/DeviceId/Components/FuncComponent.cs b/src/DeviceId/Components/FuncComponent.cs new file mode 100644 index 0000000..17eade0 --- /dev/null +++ b/src/DeviceId/Components/FuncComponent.cs @@ -0,0 +1,29 @@ +using System; + +namespace DeviceId.Components; + +/// +/// An implementation of that executes a command. +/// +public class FuncComponent : IDeviceIdComponent +{ + private readonly Func _func; + + /// + /// Initializes a new instance of the class. + /// + /// The value-function of this component. + internal FuncComponent(Func func) + { + _func = func; + } + + /// + /// Gets the component value. + /// + /// The component value. + public string GetValue() + { + return _func.Invoke(); + } +} diff --git a/src/DeviceId/Components/TextComponent.cs b/src/DeviceId/Components/TextComponent.cs new file mode 100644 index 0000000..4c43206 --- /dev/null +++ b/src/DeviceId/Components/TextComponent.cs @@ -0,0 +1,27 @@ +namespace DeviceId.Components; + +/// +/// An implementation of that executes a command. +/// +public class TextComponent : IDeviceIdComponent +{ + private readonly string _value; + + /// + /// Initializes a new instance of the class. + /// + /// The value of this component. + internal TextComponent(string value) + { + _value = value; + } + + /// + /// Gets the component value. + /// + /// The component value. + public string GetValue() + { + return _value; + } +} diff --git a/src/DeviceId/_InternalsVisibleTo.cs b/src/DeviceId/_InternalsVisibleTo.cs index f5994c3..37175f9 100644 --- a/src/DeviceId/_InternalsVisibleTo.cs +++ b/src/DeviceId/_InternalsVisibleTo.cs @@ -8,3 +8,4 @@ [assembly: InternalsVisibleTo("DeviceId.Windows.Wmi, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5bb1a0001be3481cbd50b4a86a99d4ce1f71eff5631fbacae0016ecc5273209aa9ab743f14cf1d370e63a039b9079326a35de058cc1f5f40ba86faf4ac8679ecc04241da2edc94e20582d00455cefbd484a124a1ecde382ff5281f6375c3efd96efdea6c6da248c1daa4ab8a4db0a325afd531668a67d5617d1bd0ad7c40dda")] [assembly: InternalsVisibleTo("DeviceId.Linux, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5bb1a0001be3481cbd50b4a86a99d4ce1f71eff5631fbacae0016ecc5273209aa9ab743f14cf1d370e63a039b9079326a35de058cc1f5f40ba86faf4ac8679ecc04241da2edc94e20582d00455cefbd484a124a1ecde382ff5281f6375c3efd96efdea6c6da248c1daa4ab8a4db0a325afd531668a67d5617d1bd0ad7c40dda")] [assembly: InternalsVisibleTo("DeviceId.Mac, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5bb1a0001be3481cbd50b4a86a99d4ce1f71eff5631fbacae0016ecc5273209aa9ab743f14cf1d370e63a039b9079326a35de058cc1f5f40ba86faf4ac8679ecc04241da2edc94e20582d00455cefbd484a124a1ecde382ff5281f6375c3efd96efdea6c6da248c1daa4ab8a4db0a325afd531668a67d5617d1bd0ad7c40dda")] +[assembly: InternalsVisibleTo("DeviceId.Xamarin, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5bb1a0001be3481cbd50b4a86a99d4ce1f71eff5631fbacae0016ecc5273209aa9ab743f14cf1d370e63a039b9079326a35de058cc1f5f40ba86faf4ac8679ecc04241da2edc94e20582d00455cefbd484a124a1ecde382ff5281f6375c3efd96efdea6c6da248c1daa4ab8a4db0a325afd531668a67d5617d1bd0ad7c40dda")]