Search code examples
c#.netlucenesolrsolrnet

Implementing a custom IReadOnlyMappingManager in solrnet


I am trying to implement a custom IReadOnlyMappingManager in solrnet to allow us to use our own Attribute types for decorating the properties of the documents that represent our solr index records. As I only need to replace the implementation of the GetFields and GetUniqueKey methods, the current implementation is as follows:

public class CustomMappingManager : AttributesMappingManager
{        
    public new ICollection<KeyValuePair<PropertyInfo, string>> GetFields(Type type)
    {
        IEnumerable<KeyValuePair<PropertyInfo, IndexFieldAttribute[]>> mappedProperties = this.GetPropertiesWithAttribute<IndexFieldAttribute>(type);

        IEnumerable<KeyValuePair<PropertyInfo, string>> fields = from mapping in mappedProperties
                                                                 select new KeyValuePair<PropertyInfo, string>(mapping.Key, mapping.Value[0].FieldName ?? mapping.Key.Name);

        return new List<KeyValuePair<PropertyInfo, string>>(fields);
    }

    public new KeyValuePair<PropertyInfo, string> GetUniqueKey(Type type)
    {
        KeyValuePair<PropertyInfo, string> uniqueKey;

        IEnumerable<KeyValuePair<PropertyInfo, IndexUniqueKeyAttribute[]>> mappedProperties = this.GetPropertiesWithAttribute<IndexUniqueKeyAttribute>(type);

        IEnumerable<KeyValuePair<PropertyInfo, string>> fields = from mapping in mappedProperties
                                                                 select new KeyValuePair<PropertyInfo, string>(mapping.Key, mapping.Value[0].FieldName ?? mapping.Key.Name);

        uniqueKey = fields.FirstOrDefault();

        return uniqueKey;
    }
}

This type has been successfully wired up using structuremap and the mappingManager in my concrete instance of ISolrOperations is an instance of this CustomMappingManager type.

I have followed the stack trace right down to the Viistors in the solrnet implementation that do the real work; these have the CustomMappingManager instance as intended. Unfortunately, the GetFields and GetUniqueKey methods on this type never get called and my documents are always empty.

Any ideas very welcome.


Solution

  • I have resolved this. The approach in the question was wrong way to go about it. Here is the equivalent portion of the working code for the CustomMappingManager implementation:

    public class CustomMappingManager : IReadOnlyMappingManager
    {
    
    public ICollection<SolrFieldModel> GetFields(Type type)
        {
            IEnumerable<KeyValuePair<PropertyInfo, IndexFieldAttribute[]>> mappedProperties = this.GetPropertiesWithAttribute<IndexFieldAttribute>(type);
    
            IEnumerable<SolrFieldModel> fields = from mapping in mappedProperties
                                                 select new SolrFieldModel()
                                                 {
                                                     Property = mapping.Key,
                                                     FieldName = mapping.Value[0].FieldName ?? mapping.Key.Name
                                                 };
    
            return new List<SolrFieldModel>(fields);
        }
    
    public SolrFieldModel GetUniqueKey(Type type)
        {
            SolrFieldModel uniqueKey;
    
            IEnumerable<KeyValuePair<PropertyInfo, IndexUniqueKeyAttribute[]>> mappedProperties = this.GetPropertiesWithAttribute<IndexUniqueKeyAttribute>(type);
    
            IEnumerable<SolrFieldModel> fields = from mapping in mappedProperties
                                                 select new SolrFieldModel()
                                                 {
                                                     Property = mapping.Key,
                                                     FieldName = mapping.Value[0].FieldName ?? mapping.Key.Name
                                                 };
    
            uniqueKey = fields.FirstOrDefault();
    
            if (uniqueKey == null)
            {
                throw new Exception("Index document has no unique key attribute");
            }
    
            return uniqueKey;
        }
    }