Le démarrage de mon ordinateur ce matin, j'ai affronté le problème exact pour un projet que je suis en train de travailler sur. J'ai eu quelques idées qui aboutissent à la suite de la conception et des commentaires serait plus que génial. Malheureusement, le design proposé par Josh n'est pas possible, que j'ai de travailler avec un serveur SQL server distant et ne pouvez pas activer le Distribuer Transaction Coordinator service de elle repose.
Ma solution est basée sur quelques simples, mais des modifications à mon code.
Tout d'abord, j'ai tous mes dépôts de mettre en œuvre un simple marqueur de l'interface:
/// <summary>
/// A base interface for all repositories to implement.
/// </summary>
public interface IRepository
{ }
Deuxièmement, je laisse toutes mes transactions permis de mettre en œuvre les référentiels de l'interface suivante:
/// <summary>
/// Provides methods to enable transaction support.
/// </summary>
public interface IHasTransactions : IRepository
{
/// <summary>
/// Initiates a transaction scope.
/// </summary>
void BeginTransaction();
/// <summary>
/// Executes the transaction.
/// </summary>
void CommitTransaction();
}
L'idée est que, dans tous mes dépots j'implémente cette interface et ajouter le code qui introduit de transaction directement en fonction du fournisseur (pour de faux référentiels j'ai fait une liste des délégués qui sera exécuté lors de la validation). Pour LINQ to SQL, il serait facile de faire des implémentations telles que:
#region IHasTransactions Members
public void BeginTransaction()
{
_db.Transaction = _db.Connection.BeginTransaction();
}
public void CommitTransaction()
{
_db.Transaction.Commit();
}
#endregion
Bien sûr, cela nécessite qu'un nouveau référentiel de la classe est créée pour chaque thread, mais c'est raisonnable pour mon projet.
Chaque méthode à l'aide du référentiel doit invoquer l' BeginTransaction()
et de la EndTransaction()
, si le dépôt n'implémente IHasTransactions
. Pour faire cet appel est encore plus facile, je suis venu avec les extensions suivantes:
/// <summary>
/// Extensions for spawning and subsequently executing a transaction.
/// </summary>
public static class TransactionExtensions
{
/// <summary>
/// Begins a transaction if the repository implements <see cref="IHasTransactions"/>.
/// </summary>
/// <param name="repository"></param>
public static void BeginTransaction(this IRepository repository)
{
var transactionSupport = repository as IHasTransactions;
if (transactionSupport != null)
{
transactionSupport.BeginTransaction();
}
}
public static void CommitTransaction(this IRepository repository)
{
var transactionSupport = repository as IHasTransactions;
if (transactionSupport != null)
{
transactionSupport.CommitTransaction();
}
}
}
Les commentaires sont appréciés!