Привет, я использую Unity для управления моими уровнями обслуживания, которые, в свою очередь, разговаривают с UnitOfWork, который управляет всеми репозиториями.UnitOfWork с Unity и Entity Framework
Некоторые из моих услуг называют другие услуги, мой вопрос в том, как я могу передать один и тот же UnitOfWork между уровнями обслуживания?
В моем случае все действия контроллера инициируются из графического интерфейса пользователя при каждом действии или событии каждой кнопки на таймере, поэтому у меня есть фабрика для создания UnitOfWork по требованию, но это вызывает проблемы, поскольку я не знаю, как пройти это UnitOfWork между службами.
Особенно сложно знать, как получить этот конкретный экземпляр экземпляра UnitOfWork, введенный в конструктор службы. Обратите внимание, что некоторые из служб могут быть длинными (10 минут или около того в фоновом потоке), я не знаю, влияет ли это на дизайн или нет.
В настоящее время служба, вызываемая из другой службы, создает собственный UnitOfWork, который вызывает проблемы как для транзакционного проектирования, так и для отслеживания сущности Entity.
Предложения приветствуются!
class OtherService : IOtherService
{
public OtherService(IUnitOfWorkFactory unitOfworkFactory,
ISettingsService settingsService)
{
UnitOfWorkFactory = unitOfworkFactory;
SettingsService = settingsService;
}
IUnitOfWorkFactory UnitOfWorkFactory;
ISettingsService SettingsService;
function SomeSeviceCall()
{
// Perhaps one way is to use a factory to instantiate a
// SettingService, and pass in the UnitOfWork here?
// Ideally it would be nice for Unity to handle all of
// the details regardless of a service being called from
// another service or called directly from a controller
// ISettingsService settingsService =
// UnityContainer.Resolve<ISettingService>();
using (var uow = UnitOfWorkFactory.CreateUnitOfWork())
{
var companies = uow.CompaniesRepository.GetAll();
foreach(Company company in companies)
{
settingsService.SaveSettings(company, "value");
company.Processed = DateTime.UtcNow();
}
uow.Save();
}
}
}
class SettingsService : ISettingsService
{
public SettingsService(IUnitOfWorkFactory unitOfworkFactory)
{
UnitOfWorkFactory = unitOfworkFactory;
}
IUnitOfWorkFactory UnitOfWorkFactory;
// ISettingsService.SaveSettings code in another module...
function void ISettingsService.SaveSettings(Company company,
string value)
{
// this is causing an issue as it essentially creates a
// sub-transaction with the new UnitOfWork creating a new
// Entiy Framework context
using (var uow = UnitOfWorkFactory.CreateUnitOfWork())
{
Setting setting = new Setting();
setting.CompanyID = company.CompanyID;
setting.SettingValue = value;
uow.Insert(setting);
uow.Save();
}
}
}
Посмотрите на [этот вопрос] (http://stackoverflow.com/questions/10585478/one-dbcontext-per-web-request-why). Я думаю, что [выбранный ответ] (http://stackoverflow.com/a/10588594/264697) также касается вашего вопроса. – Steven
@Steven спасибо, мне нравится идея дизайна команды/обработчика, как можно было бы получить контекст, разделенный на несколько сервисов, с помощью декоратора команд? Если у вас есть примеры кода вызывающего декоратора и возвращенных данных, которые будут иметь огромное значение. – g18c
Я пропустил тот факт, что вы используете Unity. С Unity чрезвычайно сложно зарегистрировать общие декораторы (хотя вы можете заставить его работать с поддержкой перехвата Unity).Однако теоретически это просто вопрос определения декоратора (скажем, «TransactionCommandHandlerDecorator»), который получает введенную единицу работы и вызывает «uwo.Save» в методе «Handle», сразу после вызова 'украденного.Handle (command) '. Вы регистрируете этот декоратор, который будет обернут вокруг ваших обработчиков команд и зарегистрируйте единицу работы с образом жизни «на веб-запрос». – Steven