FFImageLoading.Compat icon indicating copy to clipboard operation
FFImageLoading.Compat copied to clipboard

Fixed Configuration duplication issue. Now only one instance of Configuration is shared among all other parts of the system.

Open kernel-coder opened this issue 2 years ago • 0 comments

:sparkles: What kind of change does this PR introduce? (Bug fix, feature, docs update...)

The RP fixes configuration-related bugs.

:arrow_heading_down: What is the current behavior?

The DI creates a Configuration instance shared among other parts of the system (ImageCache, all the implementations of IDataResolver, and especially DataResolverFactory). Then when ImageServiceBase.Configuration is accessed, it, in turn, calls InitializeIfNeeded and creates another instance of Configuration set to ImageServiceBase._config (but not that the initial instance is shared and used among other parts). Now we modify the various properties in Configuration, the changes are only to that (newly created instance) and not in one shared among other parts of the system. On a special note, it also creates a new HttpClient as well (through the same flow), so if I set authorization headers, it is not used since the initially created Configuration (hence HttpClient that was created with it) was shared among all the other parts of the codebase.

Just go ahead and execute the following method on a button-click handler and you will understand.

private async void Button_Clicked(object sender, EventArgs e)
{
	// creates a CachedImage and adds to VirtualstackPanel on each click
	var ci = new CachedImage() { WidthRequest = 100, HeightRequest = 100 };
	verticalStackLayout.Children.Add(ci);
	try
	{
		var imageService = ci?.FindMauiContext().Services.GetService<IImageService<TImageContainer>>();

		// BUG: Note of the following property changes has any effect due to configuraiton duplicacy

		// setup image authorization
		if (imageService.Configuration.HttpClient.DefaultRequestHeaders.Contains("Authorization"))
		{
			imageService.Configuration.HttpClient.DefaultRequestHeaders.Remove("Authorization");
		}
		imageService.Configuration.HttpClient.DefaultRequestHeaders.Add("Authorization", "Basic [SECRETS]");

		// change some other properties
		imageService.Configuration.MaxMemoryCacheSize = 1073741824;
		imageService.Configuration.VerboseLogging = true;
		imageService.Configuration.HttpReadTimeout = 100;
		imageService.Configuration.HttpClient.Timeout = TimeSpan.FromSeconds(imageService.Configuration.HttpReadTimeout);

		ci.Source = "https://cloudfour.com/examples/img-currentsrc/images/kitten-large.png";
	}
	catch (Exception ex)
	{
		throw ex;
	}
}

:new: What is the new behavior (if this is a feature change)?

It is not a feature change, just fixes configuration issues. The changes only keeps the one instances of Configuration that was created initially which is the one shared among other parts of the code through DI. If user calls ImageServiceBase.Initialize with a new instance of Configuration, we just copy over the settings to the initially created one.

:boom: Does this PR introduce a breaking change?

Nope

:bug: Recommendations for testing

Just test with the above code provided for finding the issue

:memo: Links to relevant issues/docs

:thinking: Checklist before submitting

  • [ ] All projects build
  • [ ] Follows style guide lines
  • [ ] Relevant documentation was updated
  • [ ] Rebased onto current develop

kernel-coder avatar Jan 19 '24 10:01 kernel-coder