Reputation: 137
I am using Google Vision API and its C# library.
I want to understand where should I initialize ImageAnnotatorClient
and how should I register GoogleVisionApiService
.
ImageAnnotatorClient
is used for sending images to the Google Vision API, like this _imageAnnotatorClient.DetectSafeSearchAsync(image)
First way - register service as Singleton and initialize ImageAnnotatorClient in the constructor
public class GoogleVisionApiService : IGoogleVisionApiService
{
private readonly IGoogleCredentialFactory _googleCredentialFactory;
private readonly ImageAnnotatorClient _imageAnnotatorClient;
public GoogleVisionApiService(IGoogleCredentialFactory googleCredentialFactory)
{
_googleCredentialFactory = googleCredentialFactory;
_imageAnnotatorClient = InitializeClient();
}
private ImageAnnotatorClient InitializeClient()
{
var googleCredential = _googleCredentialFactory.GetGoogleCredentialAsync().Result;
var credential = googleCredential.UnderlyingCredential as ServiceAccountCredential;
var imageAnnotatorClientBuilder = new ImageAnnotatorClientBuilder
{
Credential = credential
};
var imageAnnotatorClient = imageAnnotatorClientBuilder.Build();
return imageAnnotatorClient;
}
public async Task<SafeSearchAnnotation> GetSafeSearchAnnotationAsync(string imageBase64)
{
var image = Image.FromBytes(Convert.FromBase64String(requestImage));
var labels = await _imageAnnotatorClient.DetectSafeSearchAsync(image);
return labels;
}
}
Second way is to register service as Transient and initialize client every time service is called
public class GoogleVisionApiService : IGoogleVisionApiService
{
private readonly IGoogleCredentialFactory _googleCredentialFactory;
public GoogleVisionApiService(IGoogleCredentialFactory googleCredentialFactory)
{
_googleCredentialFactory = googleCredentialFactory;
}
public async Task<SafeSearchAnnotation> GetSafeSearchAnnotationAsync(string imageBase64)
{
var googleCredential = await _googleCredentialFactory.GetGoogleCredentialAsync();
var credential = googleCredential.UnderlyingCredential as ServiceAccountCredential;
var imageAnnotatorClientBuilder = new ImageAnnotatorClientBuilder
{
Credential = credential
};
var imageAnnotatorClient = await imageAnnotatorClientBuilder.BuildAsync();
var image = Image.FromBytes(Convert.FromBase64String(requestImage));
var labels = await _imageAnnotatorClient.DetectSafeSearchAsync(image);
return labels;
}
}
Upvotes: 1
Views: 590
Reputation: 1502406
In general, it's best to create a single RPC client if you can.
In your specific case, I'd suggest using the (relatively new) DI-friendly extension methods in the Google client libraries. Then your GoogleVisionApiService
can just accept an ImageAnnotatorClient
.
// Wherever you're configuring services
services
// Make sure everything uses the right credential
.AddSingleton<GoogleCredential>(provider => /* code to fetch credential */)
// Note: this is for .NET 6 and .NET Core 3.1. Without this line, the client builder
// will use the "right" adapter for the environment, but won't be able to hook gRPC
// logging up with the DI's logging configuration
.AddGrpcNetClientAdapter()
.AddImageAnnotatorClient();
See the client lifecycle docs for more information.
Upvotes: 1