Композиция II-рецептора NHibernate - PullRequest
1 голос
/ 03 февраля 2012

У нас есть проект, который использует объект-перехватчик, чтобы заставить NHibernate выполнить некоторые общие работы перед сохранением сущности. Этот перехватчик выполняет одну задачу. Теперь есть еще одна задача, которая должна быть добавлена ​​к этому перехватчику (NHibernate не делает поддержка нескольких перехватчиков), но я не хочу усложнять этот перехватчик. Вместо этого я хотел бы использовать композиционный шаблон, который будет управлять всеми зарегистрированными перехватчиками. Примерно так:

public bool Onload(object entity,object id,object[] state,string propertyNames,IType[] types_
{
var result=false;
foreach(var interceptor in _registeredInterceptors)
result=result || interceptor.OnLoad(entity,id,state,propertyNames,types);
return result;
}

public bool OnFlushDirty(object entity,object id,object[] state,string propertyNames,IType[] types_
{
var result=false;
foreach(var interceptor in _registeredInterceptors)
result=result || interceptor.OnFlushDirty(entity,id,state,propertyNames,types);
return result;
}

, взглянув на этот код, я понял, что может быть лучший способ не дать мне повториться. вопрос в том, можно ли сделать этот код более простым и абстрактным с помощью лямбда-выражений и ключевого слова yield?

1 Ответ

2 голосов
/ 04 февраля 2012

Один из способов сделать это может выглядеть так:

public bool Execute(IList<IInterceptor> interceptors, Func<IInterceptor, bool> func)
{
    bool result = false;
    foreach (IInterceptor interceptor in interceptors)
    {
        result = result || func(interceptor);
    }

    return result;
}

А в родительском перехватчике:

public bool Onload(object entity, object id, object[] state, string propertyNames, IType[] types_
{
    return Execute(_registeredInterceptors, x => x.OnLoad(entity, id, state, propertyNames, types);
}

public bool OnFlushDirty(object entity, object id, object[] state, string propertyNames, IType[] types_
{
    return Execute(_registeredInterceptors, x => x.OnFlushDirty(entity, id, state, propertyNames, types);
}

Обновление

Если вы хотите, чтобы тип результата был универсальным, вы можете сделать это следующим образом:

public static T Execute<T>(IList<IInterceptor> interceptors, Func<IInterceptor, T> func)
{   
    T result = default(T);
    foreach (IInterceptor interceptor in interceptors)
    {
        // your logic based on type T
    }

    return T;
}

Исполнение универсальной версии будет выглядеть точно так же, как и у bool из-за Type inference.

Это то, что вы имели в виду?

...