3 votes

Inscrire plusieurs IInterceptor dans nhibernate

Y a-t-il un moyen d'enregistrer plusieurs IInterceptor dans nhibernate

cela ne fonctionne pas dans hibernate 3.1.0.4000

config.SetInterceptor(new ContextAwareInterceptor());
config.SetInterceptor(new ContextAwareCommandInterceptor());
config.SetInterceptor(new SqlInterceptor());

7voto

hcoverlambda Points 400

Vous pouvez réaliser cela en utilisant un intercepteur composite. Voici une implémentation qui a fonctionné pour moi. Soyez simplement conscient que si vous avez plusieurs intercepteurs qui implémentent une méthode qui renvoie une valeur (comme GetEntity()), dans certains cas le premier est renvoyé et d'autres (comme FindDirty() et OnPrepareStatement()) les résultats sont combinés. Liste complète avec tests ici.

utilisation de System.Collections;
utilisation de System.Collections.Generic;
utilisation de System.Linq;
utilisation de MoreLinq;
utilisation de NHibernate;
utilisation de NHibernate.SqlCommand;
utilisation de NHibernate.Type;

public class CompositeInterceptor : IInterceptor
{
    private readonly IEnumerable _intercepteurs;

    public CompositeInterceptor(IEnumerable intercepteurs)
    {
        _intercepteurs = intercepteurs.ToList();
    }

    public void AfterTransactionBegin(ITransaction tx)
    {
        _intercepteurs.ForEach(x => x.AfterTransactionBegin(tx));
    }

    public void AfterTransactionCompletion(ITransaction tx)
    {
        _intercepteurs.ForEach(x => x.AfterTransactionCompletion(tx));
    }

    public void BeforeTransactionCompletion(ITransaction tx)
    {
        _intercepteurs.ForEach(x => x.BeforeTransactionCompletion(tx));
    }

    public int[] FindDirty(object entity, object id, object[] currentState, 
        object[] previousState, string[] propertyNames, IType[] types)
    {
        var results = _intercepteurs
            .Select(intercepteur => intercepteur.FindDirty(entity, id,
                currentState, previousState, propertyNames, types))
            .Where(result => result != null)
            .SelectMany(x => x)
            .Distinct()
            .ToArray();
        return !results.Any() ? null : results;
    }

    public object GetEntity(string entityName, object id)
    {
        return _intercepteurs
            .Select(intercepteur => intercepteur.GetEntity(entityName, id))
            .FirstOrDefault(result => result != null);
    }

    public string GetEntityName(object entity)
    {
        return _intercepteurs
            .Select(intercepteur => intercepteur.GetEntityName(entity))
            .FirstOrDefault(result => result != null);
    }

    public object Instantiate(string entityName, EntityMode entityMode, object id)
    {
        return _intercepteurs
            .Select(intercepteur => intercepteur.Instantiate(entityName, entityMode, id))
            .FirstOrDefault(result => result != null);
    }

    public bool? IsTransient(object entity)
    {
        return _intercepteurs
            .Select(intercepteur => intercepteur.IsTransient(entity))
            .FirstOrDefault(result => result != null);
    }

    public void OnCollectionRecreate(object collection, object key)
    {
        _intercepteurs.ForEach(x => x.OnCollectionRecreate(collection, key));
    }

    public void OnCollectionRemove(object collection, object key)
    {
        _intercepteurs.ForEach(x => x.OnCollectionRemove(collection, key));
    }

    public void OnCollectionUpdate(object collection, object key)
    {
        _intercepteurs.ForEach(x => x.OnCollectionUpdate(collection, key));
    }

    public void OnDelete(object entity, object id, object[] state, 
        string[] propertyNames, IType[] types)
    {
        _intercepteurs.ForEach(x => x.OnDelete(entity, id, state, propertyNames, types));
    }

    public bool OnFlushDirty(object entity, object id, object[] currentState, 
        object[] previousState, string[] propertyNames, IType[] types)
    {
        return _intercepteurs.Count(intercepteur => intercepteur.OnFlushDirty(
            entity, id, currentState, previousState, propertyNames, types)) > 0;
    }

    public bool OnLoad(object entity, object id, object[] state, 
        string[] propertyNames, IType[] types)
    {
        return _intercepteurs.Count(intercepteur => intercepteur.OnLoad(
            entity, id, state, propertyNames, types)) > 0;
    }

    public SqlString OnPrepareStatement(SqlString sql)
    {
        return _intercepteurs.Aggregate(sql, (current, intercepteur) => 
            intercepteur.OnPrepareStatement(current));
    }

    public bool OnSave(object entity, object id, object[] state, 
        string[] propertyNames, IType[] types)
    {
        return _intercepteurs.Count(intercepteur => intercepteur.OnSave(
            entity, id, state, propertyNames, types)) > 0;
    }

    public void PostFlush(ICollection entités)
    {
        _intercepteurs.ForEach(x => x.PostFlush(entités));
    }

    public void PreFlush(ICollection entités)
    {
        _intercepteurs.ForEach(x => x.PreFlush(entités));
    }

    public void SetSession(ISession session)
    {
        _intercepteurs.ForEach(x => x.SetSession(session));
    }
}

2voto

Diego Mijelshon Points 40314

Vous ne pouvez pas. Une session ne peut avoir qu'un seul intercepteur.

Vous devriez plutôt examiner les Événements.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X