Репозиторий (или, тем не менее, один из них хочет называть его) в это время для меня, в основном касается абстрагирования слоя сохранения.
Я использую его в сочетании с объектами запроса, поэтому у меня нет связи с какой-либо конкретной технологией в моих приложениях. Кроме того, это значительно облегчает тестирование.
Итак, я имею тенденцию иметь
public interface IRepository : IDisposable
{
void Save<TEntity>(TEntity entity);
void SaveList<TEntity>(IEnumerable<TEntity> entities);
void Delete<TEntity>(TEntity entity);
void DeleteList<TEntity>(IEnumerable<TEntity> entities);
IList<TEntity> GetAll<TEntity>() where TEntity : class;
int GetCount<TEntity>() where TEntity : class;
void StartConversation();
void EndConversation();
//if query objects can be self sustaining (i.e. not need additional configuration - think session), there is no need to include this method in the repository.
TResult ExecuteQuery<TResult>(IQueryObject<TResult> query);
}
Возможно, добавить асинхронные методы с обратными вызовами в качестве делегатов. Репо легко реализовать в целом, поэтому я не могу коснуться строки реализации из приложения в приложение. Ну, это правда, по крайней мере, при использовании NH, я сделал это также с EF, но сделал меня ненавидеть EF. 4. Разговор - это начало транзакции. Очень классно, если несколько классов совместно используют экземпляр репозитория. Кроме того, для NH одно репо в моей реализации равно одному сеансу, который открывается при первом запросе.
Затем объекты запроса
public interface IQueryObject<TResult>
{
/// <summary>Provides configuration options.</summary>
/// <remarks>
/// If the query object is used through a repository this method might or might not be called depending on the particular implementation of a repository.
/// If not used through a repository, it can be useful as a configuration option.
/// </remarks>
void Configure(object parameter);
/// <summary>Implementation of the query.</summary>
TResult GetResult();
}
Для конфигурации, которую я использую только в NH пройти в ISession. В EF нет смысла более или менее.
Примерный запрос будет ... (NH)
public class GetAll<TEntity> : AbstractQueryObject<IList<TEntity>>
where TEntity : class
{
public override IList<TEntity> GetResult()
{
return this.Session.CreateCriteria<TEntity>().List<TEntity>();
}
}
Чтобы выполнить запрос EF, вам нужно будет иметь контекст в базе данных Abstract, а не в сеансе. Но, конечно, ifc будет одинаковым.
Таким образом, сами запросы инкапсулируются и легко проверяются. Лучше всего, мой код опирается только на интерфейсы. Все очень чисто. Доменные (бизнес-объекты) - это именно то, что, например, не происходит смешивания обязанностей, например, при использовании активного шаблона записи, который вряд ли тестируется, и смешивает код доступа к данным (запрос) в объекте домена и при этом смешивает проблемы (объект, который извлекает себя?). Все могут свободно создавать POCO для передачи данных.
В целом, многократное повторное использование кода и простота обеспечивается этим подходом при потере того, что я могу себе представить. Любые идеи?
И большое спасибо Айенде за его большие посты и постоянную преданность делу. Его идеи здесь (объект запроса), а не мои.
Я решил это. Проблема заключалась в том, что node-jose
создает JWE.KEY
экземпляр, в котором значение ключа закодировано Base64
. Поэтому мне пришлось перевести мой ключ из hexBinary
представления в Base64
закодированное представление.