OrchardCMS / OrchardCore

Orchard Core is an open-source modular and multi-tenant application framework built with ASP.NET Core, and a content management system (CMS) built on top of that framework.
https://orchardcore.net
BSD 3-Clause "New" or "Revised" License
7.42k stars 2.39k forks source link

Creating a Taxonomy item in Migrations throws ObjectDisposedException #3721

Closed barthamark closed 5 years ago

barthamark commented 5 years ago

Since TaxonomyField requires a TaxonomyContentItemId in their field settings we need to create a Taxonomy content item in the related Migrations step if it doesn't exist already or it's a fresh setup.

What I did is the following:

public async Task<int> CreateAsync()
{
            ...
            var taxonomy = await _contentManager.NewAsync("Taxonomy");
            taxonomy.DisplayText = "My Taxonomy";
            var taxonomyPart = taxonomy.As<TaxonomyPart>();
            taxonomyPart.TermContentType = "MyTermType";
            taxonomy = taxonomy.Apply(taxonomyPart);
            await _contentManager.CreateAsync(taxonomy, VersionOptions.Published);
            ...

but it throw an exception:

2019-05-29 15:00:54.4982|Default|0HLN46M7H0KUT:0000000A||Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware|ERROR|An unhandled exception has occurred while executing the request. System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'IServiceProvider'.
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ThrowHelper.ThrowObjectDisposedException()
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at OrchardCore.Taxonomies.Indexing.TaxonomyIndexProvider.<Describe>b__4_0(ContentItem contentItem) in C:\Agent2\work\OCORE-Lombiq\src\OrchardCore.Modules\OrchardCore.Taxonomies\Indexing\TaxonomyIndex.cs:line 54
   at YesSql.Indexes.IndexDescriptor`3.<>c__DisplayClass10_0.<Map>b__0(T x) in C:\projects\yessql-un1yf\src\YesSql.Abstractions\Indexes\DescribeFor.cs:line 54
   at YesSql.Indexes.IndexDescriptor`3.<YesSql.Indexes.IDescribeFor.GetMap>b__17_0(Object x) in C:\projects\yessql-un1yf\src\YesSql.Abstractions\Indexes\DescribeFor.cs:line 113
   at YesSql.Session.MapNew(Document document, Object obj) in C:\projects\yessql-un1yf\src\YesSql.Core\Session.cs:line 791
   at YesSql.Session.SaveEntityAsync(Object entity) in C:\projects\yessql-un1yf\src\YesSql.Core\Session.cs:line 189
   at YesSql.Session.FlushAsync() in C:\projects\yessql-un1yf\src\YesSql.Core\Session.cs:line 498
   at YesSql.Session.Dispose() in C:\projects\yessql-un1yf\src\YesSql.Core\Session.cs:line 428
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.Dispose()
   at OrchardCore.Hosting.ShellBuilders.ShellContext.ServiceScopeWrapper.Dispose() in C:\Agent2\work\OCORE-Lombiq\src\OrchardCore\OrchardCore.Abstractions\Shell\Builders\ShellContext.cs:line 272
   at OrchardCore.Modules.ModularTenantContainerMiddleware.Invoke(HttpContext httpContext) in C:\Agent2\work\OCORE-Lombiq\src\OrchardCore\OrchardCore\Modules\ModularTenantContainerMiddleware.cs:line 91
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)    at Microsoft.Extensions.DependencyInjection.ServiceLookup.ThrowHelper.ThrowObjectDisposedException()
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at OrchardCore.Taxonomies.Indexing.TaxonomyIndexProvider.<Describe>b__4_0(ContentItem contentItem) in C:\Agent2\work\OCORE-Lombiq\src\OrchardCore.Modules\OrchardCore.Taxonomies\Indexing\TaxonomyIndex.cs:line 54
   at YesSql.Indexes.IndexDescriptor`3.<>c__DisplayClass10_0.<Map>b__0(T x) in C:\projects\yessql-un1yf\src\YesSql.Abstractions\Indexes\DescribeFor.cs:line 54
   at YesSql.Indexes.IndexDescriptor`3.<YesSql.Indexes.IDescribeFor.GetMap>b__17_0(Object x) in C:\projects\yessql-un1yf\src\YesSql.Abstractions\Indexes\DescribeFor.cs:line 113
   at YesSql.Session.MapNew(Document document, Object obj) in C:\projects\yessql-un1yf\src\YesSql.Core\Session.cs:line 791
   at YesSql.Session.SaveEntityAsync(Object entity) in C:\projects\yessql-un1yf\src\YesSql.Core\Session.cs:line 189
   at YesSql.Session.FlushAsync() in C:\projects\yessql-un1yf\src\YesSql.Core\Session.cs:line 498
   at YesSql.Session.Dispose() in C:\projects\yessql-un1yf\src\YesSql.Core\Session.cs:line 428
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.Dispose()
   at OrchardCore.Hosting.ShellBuilders.ShellContext.ServiceScopeWrapper.Dispose() in C:\Agent2\work\OCORE-Lombiq\src\OrchardCore\OrchardCore.Abstractions\Shell\Builders\ShellContext.cs:line 272
   at OrchardCore.Modules.ModularTenantContainerMiddleware.Invoke(HttpContext httpContext) in C:\Agent2\work\OCORE-Lombiq\src\OrchardCore\OrchardCore\Modules\ModularTenantContainerMiddleware.cs:line 91
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Based on this answer by @jtkech : https://github.com/OrchardCMS/OrchardCore/issues/3191#issuecomment-466179170

_session.CommitAsync() worked when I called it right after the CreateAsync.

However, I am not sure if this is the best idea to commit the transaction in the middle of the Migrations pipeline.

sebastienros commented 5 years ago

Can you try with a FlushAsync ?

jtkech commented 5 years ago

@barthamark can you try it again with the dev branch where we now commit the session automatically before disposing the shell scope.

barthamark commented 5 years ago

It seems that it's working. I was testing with the latest preview NuGet packages and there was no exceptions during the Migrations and the taxonomy was created successfully. Thanks! I'll close this issue now.