Skip to content
Open
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
6 changes: 5 additions & 1 deletion Exadel.Compreface/Clients/ApiClient/ApiClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using Exadel.Compreface.Configuration;
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Exadel.Compreface.Configuration;
using Flurl.Http.Content;
using Flurl.Http;
using Flurl;
Expand Down
6 changes: 5 additions & 1 deletion Exadel.Compreface/Clients/ApiClient/IApiClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using Flurl;
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Flurl;
using Flurl.Http.Content;

namespace Exadel.Compreface.Clients.ApiClient
Expand Down
200 changes: 105 additions & 95 deletions Exadel.Compreface/Clients/CompreFaceClient/CompreFaceClient.cs
Original file line number Diff line number Diff line change
@@ -1,126 +1,136 @@
using Exadel.Compreface.Configuration;
using System;
using System.Collections.Generic;
using Exadel.Compreface.Configuration;
using Exadel.Compreface.Exceptions;
using Exadel.Compreface.Services.Attributes;
using Microsoft.Extensions.Configuration;
using System.Reflection;
using Exadel.Compreface.Helpers;

namespace Exadel.Compreface.Clients.CompreFaceClient;

/// <summary>
/// Global CompreFace provider.
/// </summary>
public class CompreFaceClient : ICompreFaceClient
namespace Exadel.Compreface.Clients.CompreFaceClient
{
private readonly string _domain;
private readonly string _port;

private readonly Dictionary<ServiceDictionaryKey, object> _services = new();

/// <summary>
/// Constructor for string parameters.
/// Global CompreFace provider.
/// </summary>
/// <param name="domain">Domain with protocol where CompreFace is located.</param>
/// <param name="port">CompreFace port.</param>
/// <exception cref="ArgumentNullException">Is throwed if one of the parameters is null.</exception>
public CompreFaceClient(string? domain, string? port)
public class CompreFaceClient : ICompreFaceClient
{
_domain = domain ?? throw new ArgumentNullException($"{nameof(domain)} cannot be null!");
_port = port ?? throw new ArgumentNullException($"{nameof(port)} cannot be null!");
}
private readonly string _domain;
private readonly string _port;

private readonly Dictionary<ServiceDictionaryKey, object>
_services = new Dictionary<ServiceDictionaryKey, object>();

/// <summary>
/// Constructor for string parameters.
/// </summary>
/// <param name="domain">Domain with protocol where CompreFace is located.</param>
/// <param name="port">CompreFace port.</param>
/// <exception cref="ArgumentNullException">Is throwed if one of the parameters is null.</exception>
public CompreFaceClient(string domain, string port)
{
_domain = domain ?? throw new ArgumentNullException($"{nameof(domain)} cannot be null!");
_port = port ?? throw new ArgumentNullException($"{nameof(port)} cannot be null!");
}

/// <summary>
/// Constructor allows to setup CompreFaceClient from appsettings.json.
/// </summary>
/// <param name="configuration">IConfiguration object.</param>
/// <param name="domainSection">Name of the section for domain parameter in an appsetting.json file.</param>
/// <param name="portSection">Name of the section for port parameter in an appsetting.json file.</param>
/// <exception cref="ArgumentNullException">Is throwed if one of the sections in appseting.json doesn't have a value.</exception>
public CompreFaceClient(IConfiguration configuration, string? domainSection, string? portSection)
{
_domain = configuration.GetSection(domainSection).Value ?? throw new ArgumentNullException($"{nameof(domainSection)} cannot be null!");
_port = configuration.GetSection(portSection).Value ?? throw new ArgumentNullException($"{nameof(portSection)} cannot be null!");
}
/// <summary>
/// Constructor allows to setup CompreFaceClient from appsettings.json.
/// </summary>
/// <param name="configuration">IConfiguration object.</param>
/// <param name="domainSection">Name of the section for domain parameter in an appsetting.json file.</param>
/// <param name="portSection">Name of the section for port parameter in an appsetting.json file.</param>
/// <exception cref="ArgumentNullException">Is throwed if one of the sections in appseting.json doesn't have a value.</exception>
public CompreFaceClient(IConfiguration configuration, string domainSection, string portSection)
{
_domain = configuration.GetSection(domainSection).Value ??
throw new ArgumentNullException($"{nameof(domainSection)} cannot be null!");
_port = configuration.GetSection(portSection).Value ??
throw new ArgumentNullException($"{nameof(portSection)} cannot be null!");
}

/// <summary>
/// Creates instance of the service.
/// </summary>
/// <typeparam name="T">Type of the service.</typeparam>
/// <param name="apiKey">Api key string from CompreFace.</param>
/// <exception cref="TypeNotBelongCompreFaceException">Is throwed if T doesn't belong to CompreFace services.</exception>
/// <example>var faceVerificationService = client.GetCompreFaceService<VerificationService>("00000000-0000-0000-0000-000000000004")</example>
/// <returns>Service instance.</returns>
public T GetCompreFaceService<T>(string apiKey) where T : class
{
var compreFaceService = GetService(apiKey, typeof(T));
/// <summary>
/// Creates instance of the service.
/// </summary>
/// <typeparam name="T">Type of the service.</typeparam>
/// <param name="apiKey">Api key string from CompreFace.</param>
/// <exception cref="TypeNotBelongCompreFaceException">Is throwed if T doesn't belong to CompreFace services.</exception>
/// <example>var faceVerificationService = client.GetCompreFaceService<VerificationService>("00000000-0000-0000-0000-000000000004")</example>
/// <returns>Service instance.</returns>
public T GetCompreFaceService<T>(string apiKey) where T : class
{
var compreFaceService = GetService(apiKey, typeof(T));

return (T)compreFaceService;
}
return (T)compreFaceService;
}

/// <summary>
/// Creates instance of the service with api key from appsettings.json file.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="configuration">IConfiguration object.</param>
/// <param name="apiKeySection">Name of the section for api key parameter in an appsetting.json file.</param>
/// <exception cref="TypeNotBelongCompreFaceException">Is throwed if T doesn't belong to CompreFace services.</exception>
/// <exception cref="ArgumentNullException">Is throwed if api key section in appseting.json doesn't have a value.</exception>
/// <returns>Service instance.</returns>
public T GetCompreFaceService<T>(IConfiguration configuration, string apiKeySection) where T : class
{
/// <summary>
/// Creates instance of the service with api key from appsettings.json file.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="configuration">IConfiguration object.</param>
/// <param name="apiKeySection">Name of the section for api key parameter in an appsetting.json file.</param>
/// <exception cref="TypeNotBelongCompreFaceException">Is throwed if T doesn't belong to CompreFace services.</exception>
/// <exception cref="ArgumentNullException">Is throwed if api key section in appseting.json doesn't have a value.</exception>
/// <returns>Service instance.</returns>
public T GetCompreFaceService<T>(IConfiguration configuration, string apiKeySection) where T : class
{

var apiKey = configuration.GetSection(apiKeySection).Value ?? throw new ArgumentNullException($"{nameof(apiKeySection)} cannot be null!");
var compreFaceService = GetService(apiKey, typeof(T));
var apiKey = configuration.GetSection(apiKeySection).Value ??
throw new ArgumentNullException($"{nameof(apiKeySection)} cannot be null!");
var compreFaceService = GetService(apiKey, typeof(T));

return (T)compreFaceService;
}
return (T)compreFaceService;
}

private object GetService(string apiKey, Type type)
{
try
private object GetService(string apiKey, Type type)
{
var key = new ServiceDictionaryKey(apiKey, type);
var baseService = _services.GetValueOrDefault(key);

if (baseService == null)
try
{
var config = new ComprefaceConfiguration(apiKey, _domain, _port);
var apiClient = new ApiClient.ApiClient(config);
baseService = ReturnServiceIfTypeIsValid(type, config, apiClient);
var key = new ServiceDictionaryKey(apiKey, type);
var baseService = _services.GetValueOrDefault(key);

_services.Add(key, baseService!);
}
if (baseService == null)
{
var config = new ComprefaceConfiguration(apiKey, _domain, _port);
var apiClient = new ApiClient.ApiClient(config);
baseService = ReturnServiceIfTypeIsValid(type, config, apiClient);

return baseService;
}
catch (Exception)
{
throw;
_services.Add(key, baseService);
}

return baseService;
}
catch (Exception)
{
throw;
}
}
}

private object ReturnServiceIfTypeIsValid(Type type, ComprefaceConfiguration config, ApiClient.ApiClient apiClient)
{
object baseService = null;
private object ReturnServiceIfTypeIsValid(Type type, ComprefaceConfiguration config,
ApiClient.ApiClient apiClient)
{
object baseService = null;

if (type.GetCustomAttribute(typeof(CompreFaceService)) != null)
baseService = Activator.CreateInstance(type, config, apiClient);
if (type.GetCustomAttribute(typeof(CompreFaceService)) != null)
baseService = Activator.CreateInstance(type, config, apiClient);

if (baseService == null)
throw new TypeNotBelongCompreFaceException("Type doesn't belong to CompreFace services. Class should be covered by CompreFaceService attribute.");
if (baseService == null)
throw new TypeNotBelongCompreFaceException(
"Type doesn't belong to CompreFace services. Class should be covered by CompreFaceService attribute.");

return baseService;
}
return baseService;
}

private class ServiceDictionaryKey
{
public string ApiKey { get; set; }
private class ServiceDictionaryKey
{
public string ApiKey { get; set; }

public Type Type { get; set; }
public Type Type { get; set; }

public ServiceDictionaryKey(string apiKey, Type type)
{
ApiKey = apiKey;
Type = type;
public ServiceDictionaryKey(string apiKey, Type type)
{
ApiKey = apiKey;
Type = type;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ namespace Exadel.Compreface.Clients.CompreFaceClient
{
public interface ICompreFaceClient
{
public T GetCompreFaceService<T>(string apiKey) where T : class;
T GetCompreFaceService<T>(string apiKey) where T : class;

public T GetCompreFaceService<T>(IConfiguration configuration, string apiKeySection) where T : class;
T GetCompreFaceService<T>(IConfiguration configuration, string apiKeySection) where T : class;
}
}
43 changes: 23 additions & 20 deletions Exadel.Compreface/Configuration/ComprefaceConfiguration.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
namespace Exadel.Compreface.Configuration;
using System;

/// <summary>
/// Setups main parameters for the CompreFace API.
/// </summary>
public class ComprefaceConfiguration : IComprefaceConfiguration
namespace Exadel.Compreface.Configuration
{
public string Domain { get; set; }

public string Port { get; set; }

public string ApiKey { get; set; }

/// <summary>
///
/// Setups main parameters for the CompreFace API.
/// </summary>
/// <param name="apiKey">Api key of a service from CompreFace.</param>
/// <param name="domain">Domain with protocol where CompreFace is located.</param>
/// <param name="port">CompreFace port.</param>
/// <exception cref="ArgumentNullException">Is throwed if one of the parameters is null.</exception>
public ComprefaceConfiguration(string apiKey, string domain, string port)
public class ComprefaceConfiguration : IComprefaceConfiguration
{
Domain = domain ?? throw new ArgumentNullException($"{nameof(domain)} cannot be null!");
Port = port ?? throw new ArgumentNullException($"{nameof(port)} cannot be null!");
ApiKey = apiKey ?? throw new ArgumentNullException($"{nameof(apiKey)} cannot be null!");
public string Domain { get; set; }

public string Port { get; set; }

public string ApiKey { get; set; }

/// <summary>
///
/// </summary>
/// <param name="apiKey">Api key of a service from CompreFace.</param>
/// <param name="domain">Domain with protocol where CompreFace is located.</param>
/// <param name="port">CompreFace port.</param>
/// <exception cref="ArgumentNullException">Is throwed if one of the parameters is null.</exception>
public ComprefaceConfiguration(string apiKey, string domain, string port)
{
Domain = domain ?? throw new ArgumentNullException($"{nameof(domain)} cannot be null!");
Port = port ?? throw new ArgumentNullException($"{nameof(port)} cannot be null!");
ApiKey = apiKey ?? throw new ArgumentNullException($"{nameof(apiKey)} cannot be null!");
}
}
}
13 changes: 7 additions & 6 deletions Exadel.Compreface/Configuration/IComprefaceConfiguration.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
namespace Exadel.Compreface.Configuration;

public interface IComprefaceConfiguration
namespace Exadel.Compreface.Configuration
{
public string Domain { get; }
public interface IComprefaceConfiguration
{
string Domain { get; }

public string Port { get; }
string Port { get; }

public string ApiKey { get; }
string ApiKey { get; }
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
using Exadel.Compreface.DTOs.HelperDTOs.BaseDTOs;

namespace Exadel.Compreface.DTOs.FaceCollectionDTOs.AddSubjectExample;

/// <summary>
/// DTO helps to create an example of the subject by saving images.
/// </summary>
public class AddSubjectExampleRequestByFilePath : BaseExampleRequest
namespace Exadel.Compreface.DTOs.FaceCollectionDTOs.AddSubjectExample
{
/// <summary>
/// Full file path.
/// DTO helps to create an example of the subject by saving images.
/// </summary>
public string FilePath { get; set; }
public class AddSubjectExampleRequestByFilePath : BaseExampleRequest
{
/// <summary>
/// Full file path.
/// </summary>
public string FilePath { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
namespace Exadel.Compreface.DTOs.FaceCollectionDTOs.AddSubjectExample;
using System;

public class AddSubjectExampleResponse
namespace Exadel.Compreface.DTOs.FaceCollectionDTOs.AddSubjectExample
{
public Guid ImageId { get; set; }
public class AddSubjectExampleResponse
{
public Guid ImageId { get; set; }

public string Subject { get; set; }
public string Subject { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace Exadel.Compreface.DTOs.FaceCollectionDTOs.DeleteImageById
using System;

namespace Exadel.Compreface.DTOs.FaceCollectionDTOs.DeleteImageById
{
public class DeleteImageByIdRequest
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace Exadel.Compreface.DTOs.FaceCollectionDTOs.DeleteImageById
using System;

namespace Exadel.Compreface.DTOs.FaceCollectionDTOs.DeleteImageById
{
public class DeleteImageByIdResponse
{
Expand Down
Loading