Singletone IReviewTypeService in nopCommerce 4.30

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
Hace 2 años
Hi there.

I'm trying to implement caching for certain methods of overridden ProductModelFactory within our plugin.
Here is the code:

public override ProductReviewsModel PrepareProductReviewsModel(ProductReviewsModel model, Product product)
{
            var cacheKey = _cacheKeyService.PrepareKeyForDefaultCache(ProductReviewsCacheKeys.ProductReviewsModelByProductIdCacheKey, product.Id);
            var productReviewsModelSource = _staticCacheManager.Get(cacheKey, () => base.PrepareProductReviewsModel(new ProductReviewsModel(), product));
            //other code
}


The problem is that sometimes randomly we get the following error:
System.ObjectDisposedException: IDataContext is disposed, see https://github.com/linq2db/linq2db/wiki/Managing-data-connection
Object name: 'DataConnection'.
   at LinqToDB.Data.DataConnection.CheckAndThrowOnDisposed()
   at LinqToDB.Data.DataConnection.LinqToDB.IDataContext.GetQueryRunner(Query query, Int32 queryNumber, Expression expression, Object[] parameters)
   at LinqToDB.DataContext.LinqToDB.IDataContext.GetQueryRunner(Query query, Int32 queryNumber, Expression expression, Object[] parameters)
   at LinqToDB.Linq.QueryRunner.ExecuteQuery[T](Query query, IDataContext dataContext, Mapper`1 mapper, Expression expression, Object[] ps, Int32 queryNumber)+MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Microsoft.Extensions.Caching.Memory.CacheExtensions.GetOrCreate[TItem](IMemoryCache cache, Object key, Func`2 factory)
   at Nop.Core.Caching.MemoryCacheManager.Get[T](CacheKey key, Func`1 acquire) in D:\a\1\s\src\Libraries\Nop.Core\Caching\MemoryCacheManager.cs:line 79
   at Nop.Web.Factories.ProductModelFactory.PrepareProductReviewsModel(ProductReviewsModel model, Product product) in D:\a\1\s\src\Presentation\Nop.Web\Factories\ProductModelFactory.cs:line 1441
   at Microsoft.Extensions.Caching.Memory.CacheExtensions.GetOrCreate[TItem](IMemoryCache cache, Object key, Func`2 factory)
   at Nop.Core.Caching.MemoryCacheManager.Get[T](CacheKey key, Func`1 acquire) in D:\a\1\s\src\Libraries\Nop.Core\Caching\MemoryCacheManager.cs:line 79
   at Nop.Plugin.Misc.INKredible.Factories.FactoriesOverridden.ProductModelFactoryOverriden.PrepareProductReviewsModel(ProductReviewsModel model, Product product) in D:\a\1\s\src\Plugins\Nop.Plugin.Misc.INKredible\Factories\FactoriesOverridden\ProductModelFactoryOverriden.cs:line 173
   at Nop.Plugin.Misc.INKredible.Factories.MicrodataSnippetsModelFactory.PrepareProductModel(Product product, ProductDetailsModel productDetailsModel) in D:\a\1\s\src\Plugins\Nop.Plugin.Misc.INKredible\Factories\MicrodataSnippetsModelFactory.cs:line 72
   at Nop.Plugin.Misc.INKredible.WidgetZoneComponents.MicrodataSnippets.ProductBoxSnippet.Invoke(ViewComponent baseViewComponent, String widgetZone, Object additionalData) in D:\a\1\s\src\Plugins\Nop.Plugin.Misc.INKredible\WidgetZoneComponents\MicrodataSnippets\ProductBoxSnippet.cs:line 39
   at Nop.Plugin.Misc.INKredible.Extensions.ViewComponentExtensions.<>c__DisplayClass0_0.<RenderWidgetZoneViewComponentParts>b__1(WidgetZoneViewComponentPart i) in D:\a\1\s\src\Plugins\Nop.Plugin.Misc.INKredible\Extensions\ViewComponentExtensions.cs:line 29
   at System.Collections.Generic.List`1.ForEach(Action`1 action)
   at Nop.Plugin.Misc.INKredible.Extensions.ViewComponentExtensions.RenderWidgetZoneViewComponentParts(ViewComponent baseViewComponent, String widgetZone, Object additionalData) in D:\a\1\s\src\Plugins\Nop.Plugin.Misc.INKredible\Extensions\ViewComponentExtensions.cs:line 36

The issue looks like to be happening here:
 foreach (var q in _reviewTypeService.GetProductReviewReviewTypeMappingsByProductReviewId(pr.Id))


When i started to look into this i've found that IReviewTypeService is registered as singleton in nop 4.30 Nop.Web.Framework.Infrastructure.DependencyRegistrar:
builder.RegisterType<ReviewTypeService>().As<IReviewTypeService>().SingleInstance();

Which may cause the issue, because of db connection in that service is re-used (or attempted to do so) within whole app lifecycle.

The question to developers: What is the purpose of registering IReviewTypeService as singletone or was it done by mistake ?
Hace 2 años
ellasoftware wrote:
Hi there.
.....
The question to developers: What is the purpose of registering IReviewTypeService as singletone or was it done by mistake ?


Hi, ellasoftware.

There is no point in declaring IReviewTypeService as a singleton; most likely, when switching to Linq2db, we did not pay enough attention to this point. It is possible that your problem is related to this moment. This service must be registered as InstancePerLifetimeScope. At 4.40 this moment has already been fixed.
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.