I wanted to create a WCF service that would separate the Tridion Content Delivery functionality so that I wouldn't add Tridion References to my Web App. Instead of referencing Tridion.ContentDelivery.dll directly in a Web App solution I would make service calls in the data layer(This is because I need a single source of Tridion content for multiple applications). Both Web App and the WCF Service use Unity for Dependency Injection. The WCF is IIS hosted. Both are .NET 4.5
An example method that fetches the data:
public List<ContentComponent> GetRelatedContent(RelatedContentRequest request)
{
string[] results = null;
ItemTypeCriteria typeCriteria = null;
PublicationCriteria publicationCriteria = null;
ItemSchemaCriteria schemaCriteria = null;
TaxonomyKeywordCriteria taxonomyKeywordCriteria = null;
Query query = null;
ComponentPresentation presentation = null;
List<Criteria> criterias = null;
List<ComponentPresentation> componentPresentations = null;
try
{
query = new Query();
criterias = new List<Criteria>();
componentPresentations = new List<ComponentPresentation>();
publicationCriteria = new PublicationCriteria(request.PublicationId);
criterias.Add(publicationCriteria);
typeCriteria = new ItemTypeCriteria(COMPONENT_TYPE);
criterias.Add(typeCriteria);
if (request.SchemaId > 0)
{
schemaCriteria = new ItemSchemaCriteria(request.SchemaId);
criterias.Add(schemaCriteria);
}
taxonomyKeywordCriteria = new TaxonomyKeywordCriteria(request.TaxonomyUri, request.KeywordUri, request.IncludeChildKeywords);
criterias.Add(taxonomyKeywordCriteria);
query.Criteria = CriteriaFactory.And(criterias.ToArray());
results = query.ExecuteQuery();
foreach (string compURI in results)
{
using (ComponentPresentationFactory factory = new ComponentPresentationFactory(compURI))
{
presentation = factory.GetComponentPresentation(compURI, request.DynamicTemplateUri);
}
if (presentation != null && !string.IsNullOrEmpty(presentation.Content))
{
componentPresentations.Add(presentation);
}
}
}
catch (System.Exception)
{
}
finally
{
if (publicationCriteria != null) publicationCriteria.Dispose();
if (schemaCriteria != null) schemaCriteria.Dispose();
if (taxonomyKeywordCriteria != null) taxonomyKeywordCriteria.Dispose();
if (typeCriteria != null) typeCriteria.Dispose();
if (query != null) query.Dispose();
if (criterias != null) criterias.Dispose();
}
if (componentPresentations != null)
{
List<ContentComponent> result = componentPresentations.ConvertAll(c => new ContentComponent() { ComponentId = c.ComponentId, Content = c.Content });
componentPresentations.Dispose();
return result;
}
return null;
}
ContentComponent and RelatedContentRequest are my custom classes. The data is returned correctly and the service works fine when I develop but when doing some load testing I run into issues. There is a memory leak. After making about 100 requests the WCF process memory grows to about 2GB. If I use http binding for the service it reaches a plateau of about 2GB but continues to respond. If I use net.pipe or net.tcp the service becomes non responsive after about 50 requests. Inspecting with dotMemory I see a lot of memory being used by unmanaged code.
I've tried using Tridion OData service instead of Tridion Delivery Content dlls but I cannot implement every functionality required using only OData.
Am I doing something wrong? Am I not disposing the items correctly?