Waail Altaie
Waail Altaie

Reputation: 21

Repository Pattern with Fluent Nhibernate

Hello everyone I've successfully implemented the repository pattern with fluentNHibernate but i have one concern abount the ExposeConfiguration when I removed it all the methods works fine but when i adds it ,it resets the tables in the database. so i need you to take a look and give me any notes about the implementation so here is my unit of work class

 public class UnitOfWork 
{

    public static ISession  NhibernateHelper()
    {
        ISessionFactory _sessionFactory = Fluently.Configure()
            .Database(MsSqlConfiguration.MsSql2012.ConnectionString(@"Data Source=WAAIL-PC\COMPUTERENGINEER;Initial Catalog=TSQL2012;User ID=sa;Password=12345678Ce").ShowSql())
            .Mappings(x => x.FluentMappings.AddFromAssemblyOf<UsersMap>())
           //.ExposeConfiguration(cfg => new SchemaExport(cfg).Create(false, true)) //when i removed this line it doesn't
          //remove the elements from the db
            .BuildSessionFactory();

       return _sessionFactory.OpenSession();

    }}

and here is my repository pattern :

public class Repository<T> :IRepository<T> where T :BaseEntity
{

    public Repository(/*IUnitOfWork unitOfWork*/)
    {
        //_unitOfWork = (UnitOfWork)unitOfWork;
    }

    public List<T> GetAll()
    {
        using (ISession Session = UnitOfWork.NhibernateHelper())
        {
            return Session.Query<T>().ToList();
        }
    }

    public T GetById(int id)
    {
        using (ISession Session = UnitOfWork.NhibernateHelper())
        {
            return Session.Get<T>(id);
        }
    }

    public T Insert(T entity)
    {
        try
        {
            using (ISession Session = UnitOfWork.NhibernateHelper())
            {
                using (ITransaction Transaction = Session.BeginTransaction())
                {
                    Session.Save(entity);
                    Transaction.Commit();
                }
            }
            return entity;
        }
        catch (Exception)
        {

            throw;
        }
    }

    public void Update(T entity)
    {
        using (ISession Session = UnitOfWork.NhibernateHelper())
        {
            using (ITransaction Transaction = Session.BeginTransaction())
            {
                Session.Update(entity);
                Transaction.Commit();
            }
        }
    }

    public void Delete(int id)
    {
        using (ISession Session = UnitOfWork.NhibernateHelper())
        {
            using (ITransaction Transaction = Session.BeginTransaction())
            {
                Session.Delete(Session.Load<T>(id));
                Transaction.Commit();
            }
        }
    }
}

here is my usersService

public class UsersService : IUsersService
{
    private readonly IRepository<Users> _Repository;

    #region Constructor
    public UsersService(IRepository<Users> Repository)
    {
        _Repository = Repository;
    }
    #endregion

    #region Service Implementation

    public List<Users> GetListAll()
    {
        return _Repository.GetAll().ToList();
    }

    public Users GetById(int Id)
    {
        return _Repository.GetById(Id);
    }

    public Users Insert(Users user)
    {
        return _Repository.Insert(user);
    }

    public void Update(Users user)
    {
        _Repository.Update(user);
    }
    public void Delete(int Id)
    {
        _Repository.Delete(Id);
    }

    //public int execute()
    //{
    //    return _Repository.execute();
    //}


}

so what i need to know is why the Expose_configuration method causes the tables to reset... and secondly ,Am i moving in the right way in this implementation or not. if you guys have any update of improvements please tell me .. best regards.

Upvotes: 2

Views: 3910

Answers (1)

kayess
kayess

Reputation: 3394

The evil lies in details

You wrote:

... ExposeConfiguration when I removed it all the methods works fine but when i add it, it resets the tables in the database.

And that's pretty much normal way of operations, since if we look up NHiberate's SchemaExport classes Create method signature, it reads:

public void Create(Action<string> scriptAction, bool execute)

It's documentation states that Create():

Run the schema creation script

And about it parameters:

scriptAction - an action that will be called for each line of the generated ddl.

execute - if the ddl should be executed against the Database.

And you call it as:

.ExposeConfiguration(cfg => new SchemaExport(cfg).Create(false, true))

Your problem lies in that you pass true to the execute parameter, which will -as stated in documentation- execute the schema creation script, which might include drop and rerecration of existing database objects.

Why create demons?

About your second idea, I really see no benefit of adding another layer of indirection to your code, and that's where you summon unneeded demons.

The NHibernate ORM itself is an abstraction itself, why add one more generic one around it? Your Repository<T> just simply calls the already implemented generic NHibernate methods... sort of acting as Proxy to hide NHibernate, if that's intentional please pardon me, but it looks like it's not.

On a final note: your UsersService class first violates the Single responsibility principle and makes your life harder by maintaining and testing it. Second, this class is also not much more than a proxy to call the repository to return values from.

Let me illustrate the problem:

  1. Client calls UsersService.GetById(Id)
  2. Service calls _Repository.GetById(Id)
  3. Your generic abstraction Repository calls NHibernates Session.Get<T>(id)

Do you see the problem?

How easier it would be to say use a pattern that might help you in this case, that is the Command Query Separation.

Where your commands are responsible for writes, and queries about reads and both suits your use-cases.

You can read about my answers earlier about queries and commands.

Upvotes: 3

Related Questions