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.
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:
Client calls UsersService.GetById(Id)
Service calls _Repository.GetById(Id)
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.
Related
Is it necessary to close connection once query is executed explicitly calling Close method or putting the connection within Using statement? Would leaving connection open lead to connection reuse and improve SQL performance for future queries?
I am assuming that you are using latest version of Dapper.
With Dapper, there are two ways to manage connection:
Fully manage yourself:
Here, you are fully responsible for opening and closing connection. This is just like how you treat connection while working with ADO.NET.
Allow Dapper to manage it:
Dapper automatically opens the connection (if it was not opened) and closes it (if it was opened by Dapper) for you. This is similar to DataAdapter.Fill() method. I personally do not recommend this way. This may not be applicable every time. Following is what Marc Gravell says in one of the comment for this answer: https://stackoverflow.com/a/12629170/5779732
well, technically open/closed is different to disposed. If you are only going to be opening/closing around the individual calls, you might as well let dapper do it. If you are opening/closing at a wider granularity (per request, for example), it would be better for your code to do it and pass an open connection to dapper.
Below is the quote from here:
Dapper will close the connection if it needed to open it. So if you're just doing 1 quick query - let Dapper handle it. If you're doing many, you should open (once) and close at the end, with all the queries in the middle...just from an efficiency standpoint.
Ofcourse, you can call multiple queries on single connection. But, connection should be closed (by calling Close(), Dispose() method or by enclosing it in using block) to avoid resource leak. Closing connection returns it to connection pool. Involvement of connection pool improves the performance over new connection cost.
In addition to just handling connection, I suggest you implement UnitOfWork to manage transactions as well. Refer this excellent sample on GitHub.
Following source code may help you. Note that this is written for my needs; so it may not work for you as is.
public sealed class DalSession : IDisposable
{
public DalSession()
{
_connection = new OleDbConnection(DalCommon.ConnectionString);
_connection.Open();
_unitOfWork = new UnitOfWork(_connection);
}
IDbConnection _connection = null;
UnitOfWork _unitOfWork = null;
public UnitOfWork UnitOfWork
{
get { return _unitOfWork; }
}
public void Dispose()
{
_unitOfWork.Dispose();
_connection.Dispose();
}
}
public sealed class UnitOfWork : IUnitOfWork
{
internal UnitOfWork(IDbConnection connection)
{
_id = Guid.NewGuid();
_connection = connection;
}
IDbConnection _connection = null;
IDbTransaction _transaction = null;
Guid _id = Guid.Empty;
IDbConnection IUnitOfWork.Connection
{
get { return _connection; }
}
IDbTransaction IUnitOfWork.Transaction
{
get { return _transaction; }
}
Guid IUnitOfWork.Id
{
get { return _id; }
}
public void Begin()
{
_transaction = _connection.BeginTransaction();
}
public void Commit()
{
_transaction.Commit();
Dispose();
}
public void Rollback()
{
_transaction.Rollback();
Dispose();
}
public void Dispose()
{
if(_transaction != null)
_transaction.Dispose();
_transaction = null;
}
}
interface IUnitOfWork : IDisposable
{
Guid Id { get; }
IDbConnection Connection { get; }
IDbTransaction Transaction { get; }
void Begin();
void Commit();
void Rollback();
}
Now, your repositories should accept this UnitOfWork in some way. I choose Dependency Injection with Constructor.
public sealed class MyRepository
{
public MyRepository(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
}
IUnitOfWork unitOfWork = null;
//You also need to handle other parameters like 'sql', 'param' ect. This is out of scope of this answer.
public MyPoco Get()
{
return unitOfWork.Connection.Query(sql, param, unitOfWork.Transaction, .......);
}
public void Insert(MyPoco poco)
{
return unitOfWork.Connection.Execute(sql, param, unitOfWork.Transaction, .........);
}
}
And then you call it like this:
With transaction:
using(DalSession dalSession = new DalSession())
{
UnitOfWork unitOfWork = dalSession.UnitOfWork;
unitOfWork.Begin();
try
{
//Your database code here
MyRepository myRepository = new MyRepository(unitOfWork);
myRepository.Insert(myPoco);
//You may create other repositories in similar way in same scope of UoW.
unitOfWork.Commit();
}
catch
{
unitOfWork.Rollback();
throw;
}
}
Without Transaction:
using(DalSession dalSession = new DalSession())
{
//Your database code here
MyRepository myRepository = new MyRepository(dalSession.UnitOfWork);//UoW have no effect here as Begin() is not called.
myRepository.Insert(myPoco);
}
This way, instead of directly exposing connection in your calling code, you control it at one location.
More details about Repository in above code could be found here.
Please note that UnitOfWork is more than just a transaction. This code handles only transaction though. You may extend this code to cover additional roles.
Hi I start learn NHibernate and now I am trying create own repository class for NHibernate.
I found many articles about this thema. I chose this tutorial: http://dotnetslackers.com/Community/blogs/antrad/archive/2008/10/25/about-repository-pattern-and-nhibernate.aspx
I am little confuse how handle with transaction in repository.
I have repository interface:
public interface IRepository<T> where T : class
{
void Commit();
void RollBack();
void BeginTransaction();
//...
}
My question is why is good begin transaction in constructor class of repository.
This part of code is from blog on top.
public class NHibRepository<T> :IRepository<T>
where T : class
{
#region Private fields
private ISession _session;
#endregion
#region Constructor
public NHibRepository(ISession session)
{
_session = NHibernateSessionManager.Instance.GetSession();
//why begin transaction where???
_session.BeginTransaction();
}
#endregion
#region Trans
public void Commit()
{
if (session.Transaction.IsActive)
{
session.Transaction.Commit();
}
}
public void Rollback()
{
if (session.Transaction.IsActive)
{
session.Transaction.Rollback();
session.Clear();
}
}
public void BeginTransaction()
{
Rollback();
session.BeginTransaction();
}
#endregion
}
I update this repository and now I use this solution:
public class NHibRepository<T> :IRepository<T>
where T : class
{
#region Private fields
private ISession _session;
#endregion
#region Constructor
public NHibRepository(ISession session)
{
_session = session;
}
#endregion
#region Trans
public void Commit()
{
using (var trans=_session.BeginTransaction())
{
trans.Commit();
}
}
public void RollBack()
{
using (var trans = _session.BeginTransaction())
{
trans.Rollback();
}
}
public void BeginTransaction()
{
throw new NotImplementedException();
}
#endregion
}
My first question is which solution is better and why? or what is correct why?
And my second question is how open session for repository class, now I use this helper class:
public class NHibeHelper
{
private static ISessionFactory _sessionFactory;
private static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
InitializeSessionFactory();
return _sessionFactory;
}
}
private static void InitializeSessionFactory()
{
_sessionFactory = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(
#"Server=Zues\SQLEXPRESS;Database=TEST;Trusted_Connection=True;")
)
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<UserMap>().Conventions.Add(DefaultCascade.All()))
.ExposeConfiguration(cfg => new SchemaUpdate(cfg).Execute(true, true))
.BuildSessionFactory();
}
public static ISession OpenSession()
{
return SessionFactory.OpenSession();
}
}
On use like this:
_userRepo = new NHibRepository<User>(NHibeHelper.OpenSession());
Looking at the two options you've presented for transaction management, they both actually have issues.
In example 1, the transaction isn't necessarily disposed, and also you're linking the lifetime of the transaction to the lifetime of the repository. This isn't necessarily a bad thing but unless you're using an IoC container or some other method to ensure that the repository is recreated for each database operation, you will only be able to commit once, and subsequent commits will probably fail.
Example 2 will unfortunately not work at all - in Commit/RollBack you are starting a new transaction every time. Especially in the case of RollBack, if this was called from external code while in the context of a transaction, all you will do is start a new nested transaction and then immediately roll it back. Not very useful unfortunately.
My personal solution to your first question is to pull transaction management away from the repository by using the ambient transactions in System.Transactions. This way you still have separation as ambient transactions are provider-agnostic, but also you have more control about what of many repository operations you might be performing will be involved in the transaction, rather than always using the single-transaction-per-operation model. See http://msdn.microsoft.com/en-us/magazine/cc163527.aspx for more info.
As for your second question, I would highly recommend looking into an IoC container like Castle Windsor or Unity. The helper class you have there is far better than rebuilding the session factory and such every time, but by using an IoC container you can very easily ensure the lifetime of your session object is exactly what you want it to be. For instance, in a number of WCF Per-Call services I'm working on, I use Castle Windsor to ensure that the session is created (and injected into the repository) when the WCF operation begins, and is disposed (along with the repository) when it ends.
i have followed the pattern on this site to hook up ninject and nhibernate to my asp.net-mvc3 site.
Here is the code in my global.aspx.cs:
internal class ServiceModule : NinjectModule
{
public override void Load()
{
var helper = new NHibernateHelper(connectionString);
Bind<ISessionFactory>().ToConstant(helper.SessionFactory)
.InSingletonScope();
Bind<IUnitOfWork>().To<UnitOfWork>()
.InRequestScope();
Bind<ISession>().ToProvider(new SessionProvider())
.InRequestScope();
Bind<IIntKeyedRepository<FAQ>>().To<Repository<FAQ>>()
.InRequestScope();
}
the issue is that i now need to do Update() and Add() in my controllers;
I have this as my controller code:
public FAQController(IIntKeyedRepository<FAQ> faqRepository, IUnitOfWork unitOfWork)
{
_faqRepository = faqRepository;
_unitOfWork = unitOfWork;
}
[Authorize]
[AcceptVerbs(HttpVerbs.Post)]
[ValidateInput(false)]
public ActionResult AddFAQ(FAQ contact)
{
var c = new FAQ {Question = contact.Question, Answer = contact.Answer};
_faqRepository.Add(c);
_unitOfWork.Commit();
return RedirectToAction("Index");
}
my main question is that it feels wrong to pass in Iunitofwork in the constructor as many other actions don't need it. I only really need it for the actions where i do updates and inserts into my db. Since i am using ninject IOC on the link above it seems to say to pass this unitofwork object through IOC.
So, is there a better more optimized way to using the UnitOfWork pattern with IOC in asp.net-mvc that does call beingtransaction for every method in my controller.
An alternative way to handle transactions is to use an IActionFilter Open the transaction in OnActionExecuting and commit on OnActionExecuted
public class TransactionFilter : IActionFilter
{
private readonly ISession session;
private ITransaction transaction;
public TransactionFilter(ISession session)
{
this.session = session;
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
this.transaction = this.session.BeginTransaction();
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
try
{
if (this.transaction.IsActive)
{
if (filterContext.Exception == null)
{
this.transaction.Commit();
}
else
{
this.transaction.Rollback();
}
}
}
finally
{
this.transaction.Dispose();
}
}
}
Define an attribute to mark the actions that use a transaction:
[AttributeUsage(AttributeTargets.Method)]
public class TransactionAttribute : Attribute
{
}
Change your Ninject configuration:
internal class ServiceModule : NinjectModule
{
public override void Load()
{
var helper = new NHibernateHelper(connectionString);
Bind<ISessionFactory>().ToConstant(helper.SessionFactory)
.InSingletonScope();
Bind<ISession>().ToProvider<SessionProvider>().InRequestScope();
Bind(typeof(IRepository<>)).To(typeof(Repository<>));
Bind(typeof(IIntKeyedRepository<>)).To(typeof(Repository<>));
BindFilter<TransactionFilter>(FilterScope.Action, null)
.WhenActionMethodHas<TransactionAttribute>();
}
}
Finally change your controller:
public FAQController(IIntKeyedRepository<FAQ> faqRepository)
{
_faqRepository = faqRepository;
}
[Transaction]
[Authorize]
[AcceptVerbs(HttpVerbs.Post)]
[ValidateInput(false)]
public ActionResult AddFAQ(FAQ contact)
{
var c = new FAQ {Question = contact.Question, Answer = contact.Answer};
_faqRepository.Add(c);
return RedirectToAction("Index");
}
I generally try to keep my generic IRepository implementation hidden inside the IUnitOfWork (see below).
My other recommendation is to pass a UnitOfWorkProvider or UnitOfWorkFactory to the constructor. That way you can register the transaction scope locally. This has the added benefit of being able to resolve the IRepository or ISession as you see fit, via dependency injection or manually.
using(var uow = this.UnitOfWorkProvider.New())
{
uow.Save<Faq>(myFaq);
}
Also make sure you in your IUnitOfWork.Dispose() you clean up the transaction and any data session objects / information you might have.
I prefer to only inject my unit of work into classes that actually use them. In most cases, the persistence classes (Repository in my case) are the only ones that need the unit of work. You want to make sure you maintain a clean separation of concerns. The controller doesn't need to know about the unit of work and shouldn't be coupled to it, either.
public class FaqRepository {
public FaqRepository(IUnitOfWork unitofWork) { ... }
public void CreateQuestion(Faq faq) {
unitOfWork.Save(faq);
unitOfWork.Commit();
}
}
If you're invoking your repository from your controller, inject the repository into your controller as follows:
public class FaqController {
public FaqController(IFaqRepository faqRepository) {...}
}
Does that make sense?
I have a repository like so:
public interface IRepository
{
void Save<T>(T entity);
void Create<T>(T entity);
void Update<T>(T entity);
void Delete<T>(T entity);
IQueryable<T> GetAll<T>();
}
My question is, where should my transaction boundaries be? Should I open a new transaction on every method and commit it before returning? Or should it be around the entire repository so that the transaction is only committed when the repository is disposed/garbage collected?
Transactions should not be applied to repositories, because if more than one needs to participate in a transaction there's no way to say it.
Have a separate service tier that uses repositories and model objects to satisfy use cases. The service methods know where the transaction boundaries need to be. That's where they should be applied.
Unit of Work is definitely the way to go. If you're using SQL Server with a local database, TransactionScope will do most of the heavy lifting for you; as long as you share sessions between repositories (which you're doing through constructor injection, right...?), then you can nest these to your heart's content. By default, it enlists in the "ambient" transaction if there is one, and starts a new one if there isn't, which is exactly the behaviour you want for a unit of work.
So your repositories might look like this:
public class UserRepository : IUserRepository
{
public UserRepository(ISession session)
{
this.Session = session;
}
public void Save(User user)
{
using (TransactionScope tsc = new TransactionScope())
{
Session.Save(user);
tsc.Complete();
}
}
protected ISession Session { get; set; }
}
public class OrderRepository : IOrderRepository
{
public OrderRepository(ISession session)
{
this.Session = session;
}
public void Save(Order order)
{
using (TransactionScope tsc = new TransactionScope())
{
Session.Save(order);
tsc.Complete();
}
}
protected ISession Session { get; set; }
}
Then you can perform the complete unit of work like so:
User currentUser = GetCurrentUser();
using (TransactionScope tsc = new TransactionScope())
{
ISession session = SessionFactory.OpenSession();
Order order = new Order(...);
order.User = currentUser;
IOrderRepository orderRepository = GetOrderRepository(session);
orderRepository.Save(order);
currentUser.LastOrderDate = DateTime.Now;
IUserRepository userRepository = GetUserRepository(session);
userRepository.Save(currentUser);
tsc.Complete();
}
If you don't like TransactionScope or your environment prevents you from using it effectively then you can always implement your own UOW or use an existing implementation. Or if you're just an architectural neat-freak then you can do both - use a generic unit-of-work interface with one of the main DI libraries, and implement your concrete UOW using the TransactionScope.
One of the options is the unit of work pattern. This is already explained in several previous questions.
I'm running into issues with my ISessions in NHibernate. I keep getting "Session Closed!" errors. Can some one please show me the correct pattern including a definition of the following methods and when to use each:
ISession.Close()
ISession.Dispose()
ISession.Disconnect()
Here's my problem. I have a callback setup to fire off a process that awards badges to players every couple of minutes. However I keep getting "Session Closed!" errors or errors about not being able to associate collections.
Here's my Repository:
public class NHibernateRepository : IRepository
{
#region Fields
private ISession _session;
private readonly ISessionFactory _sessionFactory;
#endregion
#region Constructors
public NHibernateRepository(ISessionFactory sessionFactory)
{
_sessionFactory = sessionFactory;
}
#endregion
#region IRepository Implementation
public ISession OpenSession()
{
_session = _sessionFactory.OpenSession();
return _session;
}
public IQueryable<TModel> All<TModel>()
{
return _session.Linq<TModel>();
}
public void Save<TModel>(TModel model)
{
_session.Save(model);
}
public void Update<TModel>(TModel model)
{
_session.Update(model);
}
public void Delete<TModel>(TModel model)
{
_session.Delete(model);
}
public ITransaction BeginTransaction()
{
return _session.BeginTransaction();
}
public void Flush()
{
_session.Flush();
}
#endregion
}
Here's my usage. The repository is getting injected via Structure Map
private Object _awardBadgesLock = new object(); //In case the callback happens again before the previous one completes
public void AwardBadges()
{
lock (_awardBadgesLock)
{
using(session = _repository.OpenSession())
{
foreach (var user in _repository.All<User>().ToList())
{
var userPuzzles = _repository.All<Puzzle>().ByUser(user.Id).ToList();
var userVotes = _repository.All<Vote>().Where(x => x.UserId == user.Id).ToList();
var userSolutions = _repository.All<Solution>().ByUser(user.Id).ToList().Where(x => !userPuzzles.Select(y => y.Id).Contains(x.PuzzleId));
var ledPuzzles = GetPuzzlesLedByUser(user.Id);
AwardPlayerBadge(user, userSolutions);
AwardCriticBadge(user, userVotes);
AwardCreatorBadge(user, userPuzzles);
AwardRidlerBadge(user, userPuzzles);
AwardSupporterBadge(user, userVotes);
AwardPopularBadge(user, userPuzzles);
AwardNotableBadge(user, userPuzzles);
AwardFamousBadge(user, userPuzzles);
AwardLeaderBadge(user, ledPuzzles);
using (var tx = _repository.BeginTransaction())
{
_repository.Update(user);
tx.Commit();
}
}
}
}
}
You should always use session.Dispose();
The other are for very strange occurances
I advice you to read the documentation of ISession on
https://nhibernate.svn.sourceforge.net/svnroot/nhibernate/trunk/nhibernate/src/NHibernate/ISession.cs
Anyway the proper way to clean up when you are finished with the session is to dispose it (or better, surround the usage with using statement). In this case, "using" closes the session and suppresses the finalizer, i.e. it prevents the session object from unnecessarily surviving the next garbage collecting and saves the memory.
If the connection is already closed, disposing it will not throw an exception. On the other hand, closing after disposing (or after closing) throws an exception.
The documentation recommends calling disconnect instead of closing, because this releases the connection to the connection pool. You should call Reconnect before using a disconnected session.
For my needs, I always use "using" which calls Dispose and have never used the othe two functions.
The issue lies in the fact the ISession is not thread-safe. There were multiple methods being fired on separate threads that all created an instance of ISession. The issue was really with the fact that they all shared the same SessionFactory. Image both of these methods are fired off on separate threads:
ISessionFactory _sessionFactory;
void MethodOne()
{
using(ISession session = _sessionFactory.OpenSession())
{
//Do something with really quick with the session
//Then dispose of it
}
}
void MethodTwo()
{
//OpenSession() actually returns the same instance used in the
//previous method that has already disposed of the object;
using(ISession session = _sessionFactory.OpenSession())
{
//Do something with a session that has already been disposed
//throws errors
}
}
How I fixed it was basically ditching NHIbernate in these scenarios and called stored procs instead. I think it turned out to be more performant in my situation anyway.
About the problem, your method of locking is right as long as you dispose the session but probably the bug lies under another part of your codes. by the way about the design, it is better that you pass the session variable to repositories because of unit of work implementation of the session and aggregate root's transaction like this:
using (ISession session = SessionFactory.OpenSession())
{
Repository1 rep1 = new Repository1(session);
Repository2 rep1 = new Repository2(session);
Repository3 rep1 = new Repository3(session);
// some logics
using (var tx = session.BeginTransaction())
tx.Commit();
}
.
.
.