Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: Add maui and use HttpClient #788

Merged
merged 8 commits into from
Jun 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 6 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ settings) as well as cached local data that expires.

Akavache is currently compatible with:

* Xamarin.iOS / Xamarin.Mac
* Xamarin.Android
* .NET 4.5 Desktop (WPF)
* Windows Phone 8.1 Universal Apps
* Xamarin.iOS / Xamarin.Mac / Xamarin.Android / Xamarin.TVOS / Xamarin.WatchOS
* Maui iOS / Mac / Mac Catalyst / Android / TVOS
* .NET 4.6.2 (and above) and .NET 6 Desktop (WPF and WinForms)
* .NET 6.0
* Windows 10 (Universal Windows Platform)
* Tizen 4.0

Expand Down Expand Up @@ -94,27 +94,14 @@ There are four built-in locations that have some magic applied on some systems:

### Platform-specific notes

* **Xamarin.iOS / Xamarin.Mac** - No issues.

* **Xamarin.Android** - No issues.

* **.NET 4.5 Desktop (WPF)** - No issues.

* **Windows Phone 8.1 Universal Apps** - You must mark your application as `x86`
or `ARM`, or else you will get a strange runtime error about SQLitePCL_Raw not
loading correctly. You must *also* ensure that the Microsoft Visual C++ runtime
is added to your project.

* **Windows 10 (Universal Windows Platform)** - You must mark your application as `x86`
or `ARM`, or else you will get a strange runtime error about SQLitePCL_Raw not
loading correctly. You must *also* ensure that the Microsoft Visual C++ runtime
is added to your project.

* **Tizen 4.0** - No issues.

#### Handling Xamarin Linker
#### Handling Xamarin/Maui Linker

There are two options to ensure the Akavache.Sqlite3 dll will not be removed by Xamarin build tools
There are two options to ensure the Akavache.Sqlite3 dll will not be removed by Xamarin and Maui build tools

#### 1) Add a file to reference the types

Expand Down
19 changes: 0 additions & 19 deletions packages/repositories.config

This file was deleted.

35 changes: 33 additions & 2 deletions src/Akavache.Core/Akavache.Core.csproj
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
<Project Sdk="MSBuild.Sdk.Extras">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;Xamarin.iOS10;Xamarin.Mac20;Xamarin.TVOS10;MonoAndroid11.0;tizen40;net6.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netstandard2.1;Xamarin.iOS10;Xamarin.Mac20;Xamarin.TVOS10;MonoAndroid11.0;tizen40;net6.0;net6.0-android;net6.0-ios;net6.0-tvos;net6.0-macos;net6.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">$(TargetFrameworks);net462;uap10.0.16299;net6.0-windows</TargetFrameworks>
<AssemblyName>Akavache.Core</AssemblyName>
<RootNamespace>Akavache</RootNamespace>
<Description>An asynchronous, persistent key-value store for desktop and mobile applications on .NET</Description>
<PackageId>akavache.core</PackageId>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
Expand All @@ -17,6 +16,10 @@
<PackageReference Include="Splat" Version="14.*" />
</ItemGroup>

<ItemGroup>
<Using Remove="Foundation" />
</ItemGroup>

<ItemGroup>
<Compile Remove="Platforms\**\*.cs" />
<None Include="Platforms\**\*.cs" />
Expand All @@ -41,27 +44,55 @@
<Reference Include="System.Runtime.Serialization" />
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('net6.0-ios')) ">
<Compile Include="Platforms\apple-common\**\*.cs" />
<Compile Include="Platforms\xamarin-mobile\**\*.cs" />
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('Xamarin.TVOS')) ">
<Compile Include="Platforms\apple-common\**\*.cs" />
<Compile Include="Platforms\xamarin-mobile\**\*.cs" />
<Reference Include="System.Runtime.Serialization" />
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('net6.0-tvos')) ">
<Compile Include="Platforms\apple-common\**\*.cs" />
<Compile Include="Platforms\xamarin-mobile\**\*.cs" />
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('net6.0-maccatalyst')) ">
<Compile Include="Platforms\apple-common\**\*.cs" />
<Compile Include="Platforms\xamarin-mobile\**\*.cs" />
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('Xamarin.Mac')) ">
<Compile Include="Platforms\apple-common\**\*.cs" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="netstandard" />
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('net6.0-macos')) ">
<Compile Include="Platforms\apple-common\**\*.cs" />
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('MonoAndroid')) ">
<Compile Include="Platforms\android\**\*.cs" />
<Compile Include="Platforms\xamarin-mobile\**\*.cs" />
<Reference Include="System.Runtime.Serialization" />
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('net6.0-android')) ">
<Compile Include="Platforms\android\**\*.cs" />
<Compile Include="Platforms\xamarin-mobile\**\*.cs" />
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('tizen40')) ">
<Compile Include="Platforms\tizen\**\*.cs" />
<Compile Include="Platforms\xamarin-mobile\**\*.cs" />
</ItemGroup>

<ItemGroup>
<None Remove="Platforms\shared\DefaultAkavacheHttpClientFactory.cs" />
</ItemGroup>

</Project>
230 changes: 230 additions & 0 deletions src/Akavache.Core/BlobCache/BlobCache.cs.orig
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
// Copyright (c) 2022 .NET Foundation and Contributors. All rights reserved.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.

using System.Diagnostics.CodeAnalysis;
using System.Reactive.Threading.Tasks;

using Newtonsoft.Json.Bson;

using Splat;

namespace Akavache;

/// <summary>
/// A class which represents a blobbed cache.
/// </summary>
public static class BlobCache
{
private static string? _applicationName;
private static IBlobCache? _localMachine;
private static IBlobCache? _userAccount;
private static ISecureBlobCache? _secure;
private static bool _shutdownRequested;

private static IScheduler? _taskPoolOverride;

[ThreadStatic]
private static IBlobCache? _unitTestLocalMachine;

[ThreadStatic]
private static IBlobCache? _unitTestUserAccount;

[ThreadStatic]
private static ISecureBlobCache? _unitTestSecure;

static BlobCache()
{
Locator.RegisterResolverCallbackChanged(() =>
{
if (Locator.CurrentMutable is null)
{
return;
}

Locator.CurrentMutable.InitializeAkavache(Locator.Current);
});

InMemory = new InMemoryBlobCache(Scheduler.Default);
}

/// <summary>
/// Gets or sets your application's name. Set this at startup, this defines where
/// your data will be stored (usually at %AppData%\[ApplicationName]).
/// </summary>
[SuppressMessage("Design", "CA1065: Properties should not fire exceptions.", Justification = "Extreme non standard case.")]
public static string ApplicationName
{
<<<<<<< HEAD
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these merge issues, or is GitHub UI bugged?

get
{
if (_applicationName is null)
{
throw new InvalidOperationException("Make sure to set BlobCache.ApplicationName on startup");
}

return _applicationName;
}
=======
get => _applicationName ?? throw new("Make sure to set BlobCache.ApplicationName on startup");
>>>>>>> main

set => _applicationName = value;
}

/// <summary>
/// Gets or sets the local machine cache. Store data here that is unrelated to the
/// user account or shouldn't be uploaded to other machines (i.e.
/// image cache data).
/// </summary>
public static IBlobCache LocalMachine
{
get => _unitTestLocalMachine ?? _localMachine ?? (_shutdownRequested ? new ShutdownBlobCache() : null) ?? Locator.Current.GetService<IBlobCache>("LocalMachine") ?? throw new InvalidOperationException("Unable to resolve LocalMachine cache. Make sure Akavache is initialized properly.");
set
{
if (ModeDetector.InUnitTestRunner())
{
_unitTestLocalMachine = value;
_localMachine ??= value;
}
else
{
_localMachine = value;
}
}
}

/// <summary>
/// Gets or sets the user account cache. Store data here that is associated with
/// the user; in large organizations, this data will be synced to all
/// machines via NT Roaming Profiles.
/// </summary>
public static IBlobCache UserAccount
{
get => _unitTestUserAccount ?? _userAccount ?? (_shutdownRequested ? new ShutdownBlobCache() : null) ?? Locator.Current.GetService<IBlobCache>("UserAccount") ?? throw new InvalidOperationException("Unable to resolve UserAccount cache. Make sure Akavache is initialized properly.");
set
{
if (ModeDetector.InUnitTestRunner())
{
_unitTestUserAccount = value;
_userAccount ??= value;
}
else
{
_userAccount = value;
}
}
}

/// <summary>
/// Gets or sets an IBlobCache that is encrypted - store sensitive data in this
/// cache such as login information.
/// </summary>
public static ISecureBlobCache Secure
{
get => _unitTestSecure ?? _secure ?? (_shutdownRequested ? new ShutdownBlobCache() : null) ?? Locator.Current.GetService<ISecureBlobCache>() ?? throw new InvalidOperationException("Unable to resolve Secure cache. Make sure Akavache is initialized properly.");
set
{
if (ModeDetector.InUnitTestRunner())
{
_unitTestSecure = value;
_secure ??= value;
}
else
{
_secure = value;
}
}
}

/// <summary>
/// Gets or sets an IBlobCache that simply stores data in memory. Data stored in
/// this cache will be lost when the application restarts.
/// </summary>
public static ISecureBlobCache InMemory { get; set; }

/// <summary>
/// Gets or sets the DateTimeKind handling for BSON readers to be forced.
/// </summary>
/// <remarks>
/// <para>
/// By default, <see cref="BsonReader"/> uses a <see cref="DateTimeKind"/> of <see cref="DateTimeKind.Local"/> and <see cref="BsonWriter"/>
/// uses <see cref="DateTimeKind.Utc"/>. Thus, DateTimes are serialized as UTC but deserialized as local time. To force BSON readers to
/// use some other <c>DateTimeKind</c>, you can set this value.
/// </para>
/// </remarks>
public static DateTimeKind? ForcedDateTimeKind { get; set; }

/// <summary>
/// Gets or sets the Scheduler used for task pools.
/// </summary>
public static IScheduler TaskpoolScheduler
{
get => _taskPoolOverride ?? Locator.Current.GetService<IScheduler>("Taskpool") ?? TaskPoolScheduler.Default;
set => _taskPoolOverride = value;
}

/// <summary>
/// Makes sure that the system has been initialized.
/// </summary>
public static void EnsureInitialized() =>

// NB: This method doesn't actually do anything, it just ensures
// that the static constructor runs
LogHost.Default.Debug("Initializing Akavache");

/// <summary>
/// This method shuts down all of the blob caches. Make sure call it
/// on app exit and await / Wait() on it.
/// </summary>
/// <returns>A Task representing when all caches have finished shutting
/// down.</returns>
public static Task Shutdown()
{
_shutdownRequested = true;
var toDispose = new[] { LocalMachine, UserAccount, Secure, InMemory, };

var ret = toDispose.Select(x =>
{
x.Dispose();
return x.Shutdown;
}).Merge().ToList().Select(_ => Unit.Default);

return ret.ToTask();
}

private class ShutdownBlobCache : ISecureBlobCache
{
IObservable<Unit> IBlobCache.Shutdown => Observable.Return(Unit.Default);

public IScheduler Scheduler => System.Reactive.Concurrency.Scheduler.Immediate;

/// <inheritdoc />
public DateTimeKind? ForcedDateTimeKind
{
get => null;
set { }
}

public void Dispose()
{
}

public IObservable<Unit> Insert(string key, byte[] data, DateTimeOffset? absoluteExpiration = null) => Observable.Empty<Unit>();

public IObservable<byte[]> Get(string key) => Observable.Empty<byte[]>();

public IObservable<IEnumerable<string>> GetAllKeys() => Observable.Empty<IEnumerable<string>>();

public IObservable<DateTimeOffset?> GetCreatedAt(string key) => Observable.Empty<DateTimeOffset?>();

public IObservable<Unit> Flush() => Observable.Empty<Unit>();

public IObservable<Unit> Invalidate(string key) => Observable.Empty<Unit>();

public IObservable<Unit> InvalidateAll() => Observable.Empty<Unit>();

public IObservable<Unit> Vacuum() => Observable.Empty<Unit>();
}
}
2 changes: 1 addition & 1 deletion src/Akavache.Core/DependencyResolverMixin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public static void InitializeAkavache(this IMutableDependencyResolver resolver,

if (fdr?.AssemblyQualifiedName is null)
{
throw new($"Cannot find valid assembly name for the {nameof(DependencyResolverMixin)} class.");
throw new InvalidOperationException($"Cannot find valid assembly name for the {nameof(DependencyResolverMixin)} class.");
}

var assemblyName = new AssemblyName(
Expand Down
Loading