// ========================================================
namespace Kerosene.DataServices.Agnostic
{
using Kerosene.Tools;
using System;
// ====================================================
/// <summary>
/// Represents the data services functionality provided for the entities of a given type.
/// </summary>
/// <typeparam name="T">The type of the entities managed by this data service.</typeparam>
public interface IDataService<T> : IDisposableExtended where T : class
{
/// <summary>
/// The data context, or data connection, this data service is associated with.
/// </summary>
IDataLink DataLink { get; }
/// <summary>
/// Creates a new dynamic query command for the entities of this data service.
/// </summary>
IDataQuery<T> Query();
/// <summary>
/// Create a new dynamic query command for the entities of this data service, and sets the contents of its
/// 'Where' clause using the dynamic lambda expression given.
/// </summary>
/// <param name="where">A dynamic lambda expression that resolves into the contents of this clause.</param>
IDataQuery<T> Where(Func<dynamic, object> where);
/// <summary>
/// Provides a convenient way of finding the first entity in the data link's cache whose contents match the
/// ones specified by the dynamic lambda expressions. If no such entity is found in the cache then a query
/// is executed against the database to find it. If finally no entity is found then null is returned.
/// </summary>
/// <param name="specs">
/// The dynamic lambda expressions resolving into the columns and values of the entity to look for. These
/// expressions shall have the 'x => x.Column == Value' form, where the value part can be an expression that
/// resolves into any valid one understood by the underlying database.
/// </param>
T Find(params Func<dynamic, object>[] specs);
/// <summary>
/// Refreshes from the underlying database the contents of the given entity. Returns the entity found from
/// the database or null if it was not found.
/// <para>
/// The object returned may or may not be the same reference as the source entity depending upon the actual
/// contents of the internal data link's cache. Even if both are not the same the contents of the source
/// entity are also refreshed.
/// </para>
/// </summary>
/// <param name="entity">The entity to refresh.</param>
T Refresh(T entity);
/// <summary>
/// Creates a new insert command for the given entity.
/// <para>
/// Once created the command's 'Submit()' method needs to be invoked to annotate it into the data link and
/// to confirm it for future execution. Afterwards, all the changes that are annotated into the data link
/// executed at once, under an ad-hoc transaction, when the data link's 'SubmitChanges()' method is invoked.
/// </para>
/// </summary>
/// <param name="entity">The entity that will be affected by this operation.</param>
IDataInsert<T> Insert(T entity);
/// <summary>
/// Creates a new delete command for the given entity.
/// <para>
/// Once created the command's 'Submit()' method needs to be invoked to annotate it into the data link and
/// to confirm it for future execution. Afterwards, all the changes that are annotated into the data link
/// executed at once, under an ad-hoc transaction, when the data link's 'SubmitChanges()' method is invoked.
/// </para>
/// </summary>
/// <param name="entity">The entity that will be affected by this operation.</param>
IDataDelete<T> Delete(T entity);
/// <summary>
/// Creates a new update command for the given entity.
/// <para>
/// Once created the command's 'Submit()' method needs to be invoked to annotate it into the data link and
/// to confirm it for future execution. Afterwards, all the changes that are annotated into the data link
/// executed at once, under an ad-hoc transaction, when the data link's 'SubmitChanges()' method is invoked.
/// </para>
/// </summary>
/// <param name="entity">The entity that will be affected by this operation.</param>
IDataUpdate<T> Update(T entity);
}
}
// ========================================================