2010-10-20 3 views
1

Nous avons l'interface suivante que nous utilisons pour définir comment une entité doit être indexé (en utilisant Lucene):C# coulée de la liste des types génériques

public interface IIndexDefinition<T> where T : IIndexable { 
    Document Convert(T entity); 
} 

Cela signifie que nous pouvons garder notre service d'index très simple. Donc, pour indexer une entité nous avons:

IndexResult IndexEntities<TEntity>(IEnumerable<TEntity> entities, 
             IIndexDefinition<TEntity> definition) 
                where TEntity : IIndexable; 

Pour soutenir les mises à jour incrémentielles à l'index, nous avons créé une file d'attente d'index. La file d'attente d'index contient une liste de tâches sûres pour l'exécution de l'index lucene.

Essentiellement une IndexTask est juste un moyen de stocker l'entité mise à jour et la définition de l'index. La classe que nous avons actuellement:

public class IndexTask<TEntity> 
{ 
    private TEntity entity; 
    private IIndexDefinition<TEntity> definition; 

    public IndexTask(TEntity entity, IIndexDefinition<TEntity> definition) 
    { 
     this.entity = entity; 
     this.definition = definition; 
    } 

    public TEntity Entity { get { return this.entity; } } 
    public IIndexDefinition<TEntity> Definition { get { return definition; } } 
} 

Lorsqu'une entité est mise à jour nous aurons les éléments suivants dans notre gestionnaire d'événements:

 var task = new IndexTask<Car>(car, new CarIndexDefinition()); 
     IndexQueue.Instance.AddItem(task); // this doesn't work 

Et pour exécuter les tâches dans la file d'attente:

 var tasks = IndexQueue.Instance.Items; 

     var service = new IndexService(); 

     foreach (var task in tasks) { 
      service.IndexEntity(task.Entity, task.Definition); 
     } 

Ma question est de savoir comment je peux créer une liste d'objets génériques IndexTask<TEntity> sur l'IndexQueue, et les renvoyer au type d'entité pertinent lorsque j'exécute la tâche.

Depuis que mes entités implémentent l'interface IIndexable je pourrais stocker une liste de IndexTask<IIndexable> mais cela se traduira par "task.Definition" résoudre à IIndexDefinition<IIndexable> dans le code ci-dessus.

Merci Ben

Mise à jour

je pensais à exposer ce qui suit sur une classe de base pour tâche d'index "IndexTaskBase":

public abstract Type GetEntityType(); 
    public abstract Type GetDefinitionType(); 

puis remplaçant sur IndexTask:

public override Type GetEntityType() { 
     return this.entity.GetType(); 
    } 

    public override Type GetDefinitionType() { 
     return this.definition.GetType(); 
    } 

Si je stocke une liste d'IndexTaskBase dans la file d'attente, puis-je convertir mes types en utilisant ces méthodes - peut-être en utilisant System.ComponentModel.TypeConverter?

+0

Je m'étire ici, mais si vous utilisez .NET 4.0, vous devriez pouvoir utiliser les nouveaux indicateurs de co et de contravariance pour les paramètres de type d'interface (plus d'informations sur: http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-et-contravariance-faq.aspx) et marque le paramètre de type T sur l'interface IIndexDefinition comme "in". Cela devrait aider à mettre ensemble des collections de ces implémentations. – casperOne

+0

Vous avez un problème avec AddItem? Pouvez-vous ajouter la définition de cette méthode? –

+0

@Pieter - AddItem ajoute simplement l'élément à une liste. Le problème est de savoir comment définir cette liste et comment renvoyer les éléments en tant que types d'origine lors de l'énumération. –

Répondre

2

Pourriez-vous réécrire:

service.IndexEntity(task.Entity, task.Definition); 

Pour ce qui suit sur une méthode de travail:

task.IndexWithService(service); 

Puis, à l'intérieur du IndexWithService, vous pouvez faire:

service.IndexEntity(this.Entity, this.Definition); 

Le IndexWithService pourrait être implémenté sur une classe de base de Task qui n'est pas un générique et la liste peut être o f ce type.

+0

C'est exactement ce que j'ai fini par faire (eh bien j'ai utilisé une interface IIndexTask au lieu d'utiliser une classe abstraite). Incroyable ce que quelques heures loin de l'ordinateur peuvent faire! –