0

I'm using Glass.Mapper v4.5.0.4 and Sitecore 8.2 (rev. 170407).

I'm doing an import into Sitecore and am using the SitecoreService.Save(T target) method for creating and saving items. I have the SitecoreService in a using statement like this:

using (this.SiteService = new SitecoreService(this.ImportDB))
{
    // CRUD operations here...
}

The items I'm saving are all standard code-generated using TDS Code generation templates with glass attributes on the class and properties.

The service is working fine for MOST items (as I'm iterating thru them) where I'm able to either create or update the item and then save it back to sitecore. However, I get this random error at some point during the CRUD operations:

Exception: Glass.Mapper.MapperException
Message: Service has been disposed, cannot create object
Source: Glass.Mapper
    at Glass.Mapper.AbstractService.InstantiateObject(AbstractTypeCreationContext abstractTypeCreationContext)
    at Glass.Mapper.Pipelines.ObjectConstruction.Tasks.CreateConcrete.LazyObjectInterceptor.Intercept(IInvocation invocation)
    at Castle.DynamicProxy.AbstractInvocation.Proceed()
    at Castle.Proxies._ProviderTermProxy.get_CurrentItem()
    at lambda_method(Closure , Object )
    at Glass.Mapper.Sc.Configuration.SitecoreTypeConfiguration.ResolveItem(Object target, Database database)
    at Glass.Mapper.Sc.DataMappers.SitecoreFieldTypeMapper.SetFieldValue(Object value, SitecoreFieldConfiguration config, SitecoreDataMappingContext context)
    at Glass.Mapper.Sc.DataMappers.SitecoreFieldIEnumerableMapper.SetFieldValue(Object value, SitecoreFieldConfiguration config, SitecoreDataMappingContext context)
    at Glass.Mapper.Sc.DataMappers.AbstractSitecoreFieldMapper.SetField(Field field, Object value, SitecoreFieldConfiguration config, SitecoreDataMappingContext context)
    at Glass.Mapper.Sc.DataMappers.AbstractSitecoreFieldMapper.MapToCms(AbstractDataMappingContext mappingContext)
    at Glass.Mapper.ExtensionMethods.ForEach[T](IEnumerable1 list, Action1 action)
    at Glass.Mapper.Pipelines.ObjectSaving.Tasks.StandardSavingTask.Execute(ObjectSavingArgs args)
    at Glass.Mapper.Pipelines.AbstractPipelineRunner`2.Run(T args)
    at Glass.Mapper.Sc.SitecoreService.WriteToItem[T](T target, Item item, Boolean updateStatistics, Boolean silent)
    at Glass.Mapper.Sc.SitecoreService.Save[T](T target, Boolean updateStatistics, Boolean silent)

I have no idea why this is happening. I'm clearly still inside the using statement when this happens so the service has not been disposed of yet. Here is the kicker: I can still use the service for subsequent items when i trap the error in a try/catch and just move on. So it's clearly NOT disposed of yet.

Has anyone run into this and resolved it? Thanks!

1

You are assigning your SitecoreService instance to a member variable which lives outside the scope of the using statement. Don't do that. Use this instead:

using (var sitecoreService = new SitecoreService(this.ImportDB))
{
    // CRUD operations here...
}

You actually don't even need the using statement at all. If you look through the tutorials, you'll see that they don't have using statements.

2
  • Thanks for the response, Ben! However, I removed the using completely (and the class Property) and just created the SitecoreService on demand when saving was needed and I still get the same issue. – SuperTed Feb 16 '18 at 0:10
  • This is the correct answer and I gave you the win for this since it was the catalyst that eventually helped me resolve the issue. Also, as @RichardSeal pointed out, DI is the way to go for this but, unfortunately, this is not how the project is currently set up. – SuperTed Apr 21 '18 at 19:31
0

Okay, after further testing I found my issue and keep in mind this issue only appears to happen on saving an EXISTING Item, not newly created ones.

So, when I retrieve the Item from Sitecore, I was using another "using" statement to cast the Item to my glass type:

T myType = default(T);
using (var siteSvc = new SitecoreService(myItem.Database))
{
    myType = siteSvc.CreateType<T>(myItem);
}

return myType;

And then as I'm updating the item I was also using a "using" statement on the save as well (as specified in the original post):

using (var siteSvc = new SitecoreService(myItem.Database))
{
    siteSvc.Save<T>(myItem);
}

Keep in mind that these are NOT nested "using" statements - they sit in completely separate methods in the class.

At this point, I don't know why my original code worked for MOST of the items when saving and only blew up on others. Obviously, the key take away here is DO NOT use a "using" statement when instantiating a SitecoreService class. Or, at the very least, be wary of using it.

1
  • 1
    I would say the key point here is inject your dependencies, don't new them up at all. Use dependency injection and a good IoC container. – Richard Seal Feb 19 '18 at 13:31
0

Like most ORMs, Glass uses lazy-loading in order to maximize performance. The objects you obtain using SitecoreService are linked to the service. When you invoke a property, it is lazy-loaded by invoking the service again. When your using block ends, the service is disposed, and therefore can't be invoked. This will trigger your exception.

As Richard Seal points out, you should use dependency injection to manage your service's lifetime.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.