Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
refactor
  • Loading branch information
tl-Roberto-Mancinelli committed Dec 20, 2024
1 parent 70385f0 commit 93f045a
Show file tree
Hide file tree
Showing 19 changed files with 277 additions and 70 deletions.
54 changes: 49 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ Add your Client ID, Secret and Signing Key ID to `appsettings.json` or any other

### Initialize TrueLayer.NET

Register the TrueLayer client in `Startup.cs` or `Program.cs` (.NET 6.0):
Register the TrueLayer client in `Startup.cs` or `Program.cs` (.NET 9.0/.NET 8.0/.NET 6.0):

```c#
public IConfiguration Configuration { get; }
Expand All @@ -115,13 +115,57 @@ public void ConfigureServices(IServiceCollection services)
// For demo purposes only. Private key should be stored securely
options.Payments.SigningKey.PrivateKey = File.ReadAllText("ec512-private-key.pem");
}
})
// We advice to cache the auth token
.AddAuthTokenInMemoryCaching();
},
// For best performance and reliability we advice to cache the auth token
authCachingStrategy: AuthCachingStrategy.InMemory)

}
```

Alternatively you can create a class that implements `IConfigureOptions<TrueLayerOptions>` if you have more complex configuration requirements.
### Multiple TrueLayer Clients

Use keyed version of TruLayer client (.NET 9.0/.NET 8.0):

```c#
.AddKeyedTrueLayer(configuration, options =>
{
// For demo purposes only. Private key should be stored securely
var privateKey = File.ReadAllText("ec512-private-key.pem");
if (options.Payments?.SigningKey != null)
{
options.Payments.SigningKey.PrivateKey = privateKey;
}
},
configurationSectionName: "TrueLayerGbp",
serviceKey: "TrueLayerGbp",
authTokenCachingStrategy: AuthTokenCachingStrategies.InMemory)
.AddKeyedTrueLayer(configuration, options =>
{
// For demo purposes only. Private key should be stored securely
var privateKey = File.ReadAllText("ec512-private-key.pem");
if (options.Payments?.SigningKey != null)
{
options.Payments.SigningKey.PrivateKey = privateKey;
}
},
configurationSectionName: "TrueLayerEur",
serviceKey: "TrueLayerEur",
authTokenCachingStrategy: AuthTokenCachingStrategies.InMemory)
```

Use `[FromKeyedServices()]` attribute to retrieve keyed client

```c#
public GbpController([FromKeyedServices("TrueLayerGbp")]ITrueLayerClient trueLayerClient, ...
public EurController([FromKeyedServices("TrueLayerEur")]ITrueLayerClient trueLayerClient, ...
```

Or `GetRequiredKeyedService`

```c#
var GbpClient = ServiceProvider.GetRequiredKeyedService<ITrueLayerClient>("TrueLayerGbp");
var EurClient = ServiceProvider.GetRequiredKeyedService<ITrueLayerClient>("TrueLayerEur");
```

### Make a payment

Expand Down
3 changes: 1 addition & 2 deletions examples/MvcExample/Controllers/HomeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using MvcExample.Models;
using OneOf;
Expand All @@ -20,7 +19,7 @@ public class HomeController : Controller
private readonly ITrueLayerClient _trueLayerClient;
private readonly ILogger<HomeController> _logger;

public HomeController([FromKeyedServices("TrueLayerClient")]ITrueLayerClient trueLayerClient, ILogger<HomeController> logger)
public HomeController(ITrueLayerClient trueLayerClient, ILogger<HomeController> logger)
{
_trueLayerClient = trueLayerClient;
_logger = logger;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using TrueLayer;

Expand All @@ -11,7 +10,7 @@ public class MerchantAccountsController : Controller
private readonly ITrueLayerClient _trueLayerClient;
private readonly ILogger<MerchantAccountsController> _logger;

public MerchantAccountsController([FromKeyedServices("TrueLayerClient")]ITrueLayerClient trueLayerClient, ILogger<MerchantAccountsController> logger)
public MerchantAccountsController(ITrueLayerClient trueLayerClient, ILogger<MerchantAccountsController> logger)
{
_trueLayerClient = trueLayerClient;
_logger = logger;
Expand Down
3 changes: 1 addition & 2 deletions examples/MvcExample/Controllers/PayoutController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using MvcExample.Models;
using TrueLayer;
Expand All @@ -18,7 +17,7 @@ public class PayoutController : Controller
private readonly ITrueLayerClient _trueLayerClient;
private readonly ILogger<PayoutController> _logger;

public PayoutController([FromKeyedServices("TrueLayerClient")]ITrueLayerClient trueLayerClient, ILogger<PayoutController> logger)
public PayoutController(ITrueLayerClient trueLayerClient, ILogger<PayoutController> logger)
{
_trueLayerClient = trueLayerClient;
_logger = logger;
Expand Down
3 changes: 1 addition & 2 deletions examples/MvcExample/Controllers/ProvidersController.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using TrueLayer;
using TrueLayer.PaymentsProviders.Model;

Expand All @@ -11,7 +10,7 @@ public class ProvidersController : Controller
{
private readonly ITrueLayerClient _trueLayerClient;

public ProvidersController([FromKeyedServices("TrueLayerClient")]ITrueLayerClient trueLayerClient)
public ProvidersController(ITrueLayerClient trueLayerClient)
{
_trueLayerClient = trueLayerClient;
}
Expand Down
18 changes: 9 additions & 9 deletions examples/MvcExample/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using TrueLayer.Auth;
using TrueLayer.Caching;

namespace MvcExample
{
Expand All @@ -21,17 +23,15 @@ public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();

const string serviceKey = "TrueLayerClient";
services.AddTrueLayer(Configuration, options =>
{
var privateKey = File.ReadAllText("ec512-private-key.pem");
if (options.Payments?.SigningKey != null)
{
var privateKey = File.ReadAllText("ec512-private-key.pem");
if (options.Payments?.SigningKey != null)
{
options.Payments.SigningKey.PrivateKey = privateKey;
}
},
serviceKey: serviceKey)
.AddAuthTokenInMemoryCaching(serviceKey);
options.Payments.SigningKey.PrivateKey = privateKey;
}
},
authTokenCachingStrategy: AuthTokenCachingStrategies.InMemory);
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
Expand Down
1 change: 1 addition & 0 deletions src/TrueLayer/Auth/AuthApiCacheDecorator.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using TrueLayer.Caching;

namespace TrueLayer.Auth
{
Expand Down
27 changes: 27 additions & 0 deletions src/TrueLayer/Caching/AuthTokenCachingStrategies.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace TrueLayer.Caching
{
/// <summary>
/// Represents the different strategies for caching auth token
/// </summary>
public enum AuthTokenCachingStrategies
{
/// <summary>
/// No caching.
/// A new auth token is generated for each request.
/// </summary>
None,

/// <summary>
/// Add a InMemory cache to store the auth token.
/// Recommended option as it improves latency and availability
/// </summary>
InMemory,

/// <summary>
/// Add a custom caching to store the auth token.
/// To use this strategy it is required to implement <see cref="IAuthTokenCache"/> interface
/// and add the custom caching class as a singleton in DI
/// </summary>
Custom
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using TrueLayer.Auth;

namespace TrueLayer;
namespace TrueLayer.Caching;

/// <summary>
/// IAuthTokenCache can be used to provide custom implementation of Auth token caching
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Microsoft.Extensions.Caching.Memory;
using TrueLayer.Auth;

namespace TrueLayer
namespace TrueLayer.Caching
{
internal class InMemoryAuthTokenCache : IAuthTokenCache
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using TrueLayer.Auth;

namespace TrueLayer
namespace TrueLayer.Caching
{
internal class NullMemoryCache : IAuthTokenCache
{
Expand Down
34 changes: 32 additions & 2 deletions src/TrueLayer/TrueLayerClientFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using TrueLayer.Auth;
using TrueLayer.Caching;
using TrueLayer.Mandates;
using TrueLayer.MerchantAccounts;
using TrueLayer.Payments;
Expand All @@ -24,7 +25,36 @@ public TrueLayerClientFactory(IApiClient apiClient, IOptionsSnapshot<TrueLayerOp
_serviceProvider = serviceProvider;
}

public ITrueLayerClient Create(string serviceKey)
public ITrueLayerClient Create()
{
var options = _options.Value;
var auth = new AuthApi(_apiClient, options);

return new TrueLayerClient(
auth,
new Lazy<IPaymentsApi>(() => new PaymentsApi(_apiClient, auth, options)),
new Lazy<IPaymentsProvidersApi>(() => new PaymentsProvidersApi(_apiClient, auth, options)),
new Lazy<IPayoutsApi>(() => new PayoutsApi(_apiClient, auth, options)),
new Lazy<IMerchantAccountsApi>(() => new MerchantAccountsApi(_apiClient, auth, options)),
new Lazy<IMandatesApi>(() => new MandatesApi(_apiClient, auth, options)));
}

public ITrueLayerClient CreateWithCache()
{
var options = _options.Value;
var authTokenCache = _serviceProvider.GetRequiredService<IAuthTokenCache>();
var decoratedAuthApi = new AuthApiCacheDecorator(new AuthApi(_apiClient, options), authTokenCache);

return new TrueLayerClient(
decoratedAuthApi,
new Lazy<IPaymentsApi>(() => new PaymentsApi(_apiClient, decoratedAuthApi, options)),
new Lazy<IPaymentsProvidersApi>(() => new PaymentsProvidersApi(_apiClient, decoratedAuthApi, options)),
new Lazy<IPayoutsApi>(() => new PayoutsApi(_apiClient, decoratedAuthApi, options)),
new Lazy<IMerchantAccountsApi>(() => new MerchantAccountsApi(_apiClient, decoratedAuthApi, options)),
new Lazy<IMandatesApi>(() => new MandatesApi(_apiClient, decoratedAuthApi, options)));
}

public ITrueLayerClient CreateKeyed(string serviceKey)
{
var options = _options.Get(serviceKey);
var auth = new AuthApi(_apiClient, options);
Expand All @@ -38,7 +68,7 @@ public ITrueLayerClient Create(string serviceKey)
new Lazy<IMandatesApi>(() => new MandatesApi(_apiClient, auth, options)));
}

public ITrueLayerClient CreateWithCache(string serviceKey)
public ITrueLayerClient CreateWithCacheKeyed(string serviceKey)
{
var options = _options.Get(serviceKey);
var authTokenCache = _serviceProvider.GetRequiredKeyedService<IAuthTokenCache>(serviceKey);
Expand Down
Loading

0 comments on commit 93f045a

Please sign in to comment.