Domanda

Sto cercando di scrivere il mio modello di dominio come la persistenza-ignoranti possibile . L'unica cosa che sto facendo in questo momento sta segnando ogni proprietà e metodo virtual, come NHibernate prevede che, per lazy-carico.

Nel mio assemblaggio modello di dominio definisco alcune interfacce repository:

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

Poi ho un gruppo di dati . Questo farà riferimento NHibernate, si sa della sua esistenza. Questo è l'assemblea che implementa queste interfacce repository:

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

e così via.

Ora volevo implementare una funzionalità di transazione per i miei repository. Per fare ciò, vorrei aggiungere un metodo BeginTransaction sulla mia interfaccia IRepository. Tuttavia, non posso definire il tipo restituito come NHibernate.ITransaction, dal momento che voglio mantenere il modello di dominio di persistenza-ignoranti, e non essere costretti a fare riferimento assemblaggio di NHibernate dal mio assemblaggio modello di dominio.

Che cosa faresti?

Ti basta implementare un void BeginTransaction(), un void Commit(), ea metodi void RollBack() sull'interfaccia, e lasciare che l'attuazione repository gestire l'oggetto ITransaction internamente

Se non sei ancora trovare un modo per esporre l'oggetto ITransaction per lasciare che il cliente gestire la transazione direttamente con esso, invece di usare metodi di repository?

Grazie!

È stato utile?

Soluzione

Si può dare un'occhiata alla Sharp Architettura tutto ciò che ha già implementato si parla, tra generici repository con supporto transazioni. La soluzione non è che IRepository ha DbContext proprietà che incapsula le operazioni (in realtà è un'interfaccia). Questa è la prima delle opzioni che hai descritto (interfaccia transazioni personalizzati che nasconde NHibernate). E funziona bene.

Credo che si può anche ri-uso S # codice di arp, indipendentemente se si intende utilizzare il quadro completo.

Altri suggerimenti

IMO operazioni devono sempre iniziare e terminare in logica di business, in altre parole, l'operazione dovrebbe iniziare nel livello di servizio non lo strato repository e il repository dovrebbe arruolare è di per sé nella transazione, idealmente questo sarebbe stato fatto in modo implicito.

Ora, se si sta utilizzando NH quindi se il vostro servizio e depositi condividono la stessa 'session' (che si dovrebbe), allora è possibile chiamare 'BeginTransaction' nel livello di servizio e di commit o il rollback, come richiesto:

Per esempio, immaginate questo un metodo su un servizio:

  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);
        }
     }

Come i repository ottenere un riferimento alla stessa sessione può essere risolto iniettando nei costruttori o utilizzando un la SessionFactory per ottenere la sessione corrente ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top