Frage

Ich versuche, mein Domain Model als Persistenz-unwissend wie möglich zu schreiben. Das einzige, was ich jetzt tue, ist jede Eigenschaft und Methode virtual Markierung, wie NHibernate, dass für faul-Laden erfordert.

In meinem Domänenmodell Montage Ich sehe einige Repository-Schnittstellen:

public interface IRepository<TEntity> where TEntity : EntityBase {
    TEntity Get(int id);
    /* ... */
}
public interface IProductRepository : IRepository<Product> { ... }

Dann habe ich eine Daten Montage . Dieser wird NHibernate verweisen, weiß er um seine Existenz. Dies ist die Anordnung, dass Geräte dieser Repository-Schnittstellen:

public abstract class Repository<TEntity> : IRepository<TEntity> {
    public TEntity Get(ind id) { ... }
    /* ... */
}
public class ProductRepository : Repository<Product>, IProductRepository {
    /* ... */
}

und so weiter.

wollte ich jetzt , um eine Transaktion Funktionalität implementieren , um meine Repositories. Um dies zu tun, würde ich eine BeginTransaction Methode auf meiner IRepository Schnittstelle hinzufügen. Ich kann aber nicht dessen Rückgabetyp als NHibernate.ITransaction definieren, da ich das Domain-Modell Persistenz-unwissend halten will, und nicht gezwungen werden, NHibernate zu referenzieren Montag von meinem Domain-Modell Montag.

Was würden Sie tun?

Would implementieren Sie einfach eine void BeginTransaction(), ein void Commit() und eine void RollBack() Methoden auf der Schnittstelle und lassen Sie die Repository Implementierung verwaltet das ITransaction Objekt intern

Oder möchten Sie einen Weg, um finden Setzen Sie das ITransaction Objekt der Kunden zu lassen, die Transaktion direkt mit ihm zu verwalten, statt Repository Methoden verwenden?

Danke!

War es hilfreich?

Lösung

Sie können einen Blick auf die Sharp Architektur die alles bereits implementiert hat man darüber reden, einschließlich allgemeiner Repositorys mit Transaktionen zu unterstützen. Die Lösung ist, dass IRepository DbContext Eigenschaft hat, die Transaktionen (es ist tatsächlich eine Schnittstelle) kapselt. Dies ist die erste der Optionen, die Sie (individuelle Transaktionen Schnittstelle, die versteckt NHibernate) beschrieben. Und es funktioniert gut.

Ich denke, man kann sogar wiederverwendet S # arp-Code unabhängig davon, ob Sie den vollen Rahmen verwenden möchten.

Andere Tipps

IMO Transaktionen sollten immer beginnen und endet in Business-Logik, mit anderen Worten der Transaktion in der Dienstschicht nicht die Repository-Schicht beginnen sollte und das Repository sollte Selbst in der Transaktion eintragen, im Idealfall würde dies implizit erfolgen.

Nun, wenn Sie verwenden NH dann, wenn der Service und Repositorys teilen sich die gleiche ‚Sitzung‘ (was sie sollten), dann können Sie anrufen ‚Begintrans‘ in der Dienstschicht und Commit oder Rollback nach Bedarf:

Zum Beispiel vorstellen, das ein Verfahren für einen Dienst:

  public void RegisterCustomer(Customer customer)
    {
        try
        {
            using(var transaction = _session.BeginTransaction())
            {
                _customerRepository.Save(customer);
                _customerSurveyRepository.Save(customerSurvey);
                // DO What ever else you want...
                transaction.Commit();
            }
        }
        catch (Exception exn)
        {
            throw new AMException(FAILED_REGISTRATION, exn);
        }
     }

Wie die Repositories erhalten einen Verweis auf die gleiche Session kann durch Injektion in der Konstrukteurs gelöst werden oder durch eine die Session mit der aktuellen Sitzung ...

zu erhalten
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top