На самом деле подход WebService (упомянутый в каком-то другом ответе) означает, что вы перемещаете NHibernate и его логику в веб-сервис. Затем WebService предоставляет функциональность db, доступную приложению, используя методы WebService.
Практически только один пользователь для базы данных, тот, который использует WebService, и если вы хотите, чтобы пользователь приложения имел разные привилегии db, вы абстрагируете его от уровня WebService
В конце концов, приложение WinForms знает только местоположение WebService, где оно запрашивает данные через методы WebService, и вы можете применить любую необходимую меру безопасности между этими двумя конечными точками.
Для автономной работы все сводится к созданию безопасного способа сохранения ваших данных в локальном хранилище и предоставлению метода синхронизации через WebService
Я фактически сделал это, используя веб-сервис, который обменивался данными с БД, и приложение WinForm (.NET Compact Framework), которое общалось только с веб-сервисом, и в случае отсутствия покрытия сотовой сети оно сериализовало бы изменения на карте памяти ( данные не были важны, поэтому для моего случая неясные / непристойные меры безопасности, если они не были приняты)
ОБНОВЛЕНИЕ с небольшим примером в соответствии с просьбой (я нахожу странным, хотя просить пример по этому вопросу)
вы настроили ваши доменные классы и конфигурацию nhibernate и (например) ваш репозиторий в проекте типа ASP.NET WebService Application. Для простоты у меня будет только один класс веб-сервиса Foo
(в Foo.asmx.cs) и один Bar
класс домена
так что вы получите это (фактическая реализация варьируется):
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[]
}
}
и мы абстрагируем daobehaviour или просто используем nhsession напрямую, представленный в виде веб-метода.
Теперь из приложения WinForm все, что вам нужно сделать, это Add a WebReference
, который вносит все необходимые изменения в конфигурацию, но также генерирует все необходимые классы (в этом примере он создаст класс Bar
, поскольку веб-служба предоставляет его ).
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);
//lets write this to local storage
var frosties = new XmlSerializer(typeof(Bar));
TextReader reader = new StreamReader(filePath);
try
{
var persisted = (T)frosties.Deserialize(reader);
}
catch(InvalidOperationException)
{
//spock, do something
}
finally
{
reader.Close();
reader.Dispose();
}
}
}
}
Есть некоторые вещи, на которые вы должны обратить внимание:
- По сути, вы теряете ленивые вещи или, по крайней мере, теряете их в своем приложении winform. Сериализатор XML не может сериализовать прокси-серверы, поэтому вы либо лениво выбираете эти коллекции / свойства, либо используете атрибут [XmlIgnore], который, в свою очередь, делает то, что подразумевается при сериализации.
- Невозможно вернуть интерфейсы для подписей WebMethod. Они должны быть конкретными классами. Таким образом, возвращение
IList<Bar>
должно быть преобразовано в List<Bar>
или что-то вроде
- Веб-служба выполняется IIS и отображается в веб-браузере. По умолчанию будут обрабатываться только запросы локального браузера (но это можно изменить), поэтому вы можете протестировать слой доступа к данным отдельно от того, что делает ваша winform.
- Принимающая сторона (приложение winform) ничего не знает о NHibernate.
- В приведенном выше примере я сохранил то же имя для dao-методов для веб-методов; Пока вы не сохранили специфичные для nhibernate методы в вашем дао (скажем, как параметр
NHibernate.Criterions.Order
), вы, вероятно, не найдете никаких проблем. На самом деле вы можете иметь столько .asmx
классов в своем веб-сервисе, сколько захотите, возможно, даже «сопоставить» их с соответствующими дао (например, public class FooService : WebService
, public class BarService : WebService
, public class CheService : WebService
, где каждый соответствует DAO).
- Вам, вероятно, придется написать какой-то метод опроса между конечными точками, чтобы сохранить представленные данные свежими.
- Данные WebService являются подробными; чрезвычайно так. Рекомендуется заархивировать их или что-то еще перед отправкой по проводам (и, возможно, также зашифровать их)
- приложение win знает только запись конфигурации:
http://server/FWS/FooService.asmx
- По умолчанию на веб-сервисах сессия отключена. помните, что перед началом использования сеанса для пользовательских данных.
- Вам, вероятно, придется написать какую-то аутентификацию для веб-сервиса
В приведенном выше примере я возвращаю Bar[]
с Bar
, сопоставленным с nhibernate. Чаще всего это может быть не так, и вам может потребоваться написать вспомогательный класс WSBar
, в котором он адаптирует исходный класс Bar
к тому, что может потреблять веб-служба и приложение winform. Этот класс на самом деле просто носитель данных. Опять же, это зависит от степени интеграции с классами вашего домена и nhibernate, а также от того, насколько сложны ваши классы: некоторые структуры данных не могут быть сериализованы по умолчанию.
Эта модель может не соответствовать тому, что вы уже сделали со своим приложением