In fact, the WebService approach (mentioned in another answer) means that you are moving NHibernate and its logic to a web service. WebService then provides the db functionality available to the application using WebService methods.
There is only one user in the database that uses WebService, and if you want the application user to have different db privileges, you abstract it from the WebService level.
In the end, the WinForms application only knows the location of the WebService, where it requests data using the WebService methods, and you can apply any required security measure between these two endpoints.
For battery life, it comes down to providing a reliable way to save data to local storage and provide a synchronization method via WebService
I really did this using a web service that exchanged data with the database and the WinForm application (.NET Compact Framework), which spoke only with the web service, and in the absence of a cellular network, it serialized the changes on the memory card (the data was not important , so for my case, obscure / obscene security measures if they are not taken)
UPDATE with a small example as requested (I'm really weird if I ask for an example)
You have configured your domain classes and nhibernate configuration and (for example) your repository materials in a project such as ASP.NET WebService Application. For simplicity, I will have only one Foo web services class (in Foo.asmx.cs), as well as one Bar domain class
so you get this (actual implementation changes):
namespace FWS { [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. // [System.Web.Script.Services.ScriptService] public class FooService : WebService { private readonly ILog errorLogger = LogManager.GetLogger("ErrorRollingLogFileAppender"); private readonly IDaoFactory daoFactory = new DaoFactory(); private readonly ISession nhSession = HibernateSessionManager.Instance.GetSession(); } [WebMethod] public Bar[] GetFavoriteBars(string someParam, int? onceMore){ return daoFactory.GetBarDao().GetFavoriteBars(someParam, onceMore); //returns a Bar[] } }
and we abstract daobehaviour or just use nhsession directly, exposed as a web method.
Now, from the WinForm application, all you have to do is Add a WebReference , which makes all the necessary changes to the configuration and also generates all the necessary classes (in this example, it will create the Bar class, since the web service provides it).
namespace WinFormK { public class KForm(): System.Windows.Forms.Form { public void Do() { var service = new FWS.FooService(); string filePath = "C:\\temp\FooData.xml"; Bar[] fetched = service.GetFavoriteBars("yes!", null);
There are some things you should take note of:
- You essentially lose lazy stuff, or at least lose it in your winform application. An XML serializer cannot serialize proxies and, as such, you either rotate the lazy selection in these collections / properties or use the [XmlIgnore] attribute, which in turn does what it implies when serializing.
- You cannot return interfaces in WebMethod signatures. They must be concrete classes. So the return of
IList<Bar> should be converted to List<Bar> or something like that - The web service is run by IIS and displayed in a web browser. By default, only local browser requests will be served (but this can be changed) so that you can test your data access level separately from what your winform does.
- The receiving side (winform application) does not know NHibernate at all.
- In the above example, I kept the same name for dao methods for web methods; Until you store the nhibernate-specific methods in your dao (say, as the
NHibernate.Criterions.Order parameter), you probably won't find any problems. In fact, you can have as many .asmx classes in your web service as you want, maybe even “map” them to the corresponding Tao (for example, public class FooService : WebService , public class BarService : WebService , public class CheService : WebService , where each corresponds to a DAO). - You may have to write some kind of polling method between your endpoints to keep your data fresh.
- WebService data is detailed; extremely. It is advisable to fix them or something before sending them over the wire (and, possibly, also encrypt them).
- the win application only knows the configuration entry:
http://server/FWS/FooService.asmx - Web Services has a disconnected session by default. remember that before you start using a session for user data.
- You may have to write some authentication for webservice
In the above example, I am returning Bar[] with Bar mapped to nhibernate. Most often this may not be the case, and you may need to write a helper class WSBar , where it adapts the original Bar class to the needs of the web service and winform application. This class is actually a data carrier. Again, this depends on how much integration exists with your domain and nhibernate classes, as well as how muxh complicates your classes: some default data structures cannot be serialized.
This model may not match what you have already done with your application.