Несколько дней назад у меня была проблема с поточной обработкой ASP.NET. Я хотел иметь одноэлементный объект на веб-запрос. Мне на самом деле нужно это для моей единицы работы. Я хотел инстанцировать единицы работы на веб-запрос так, чтобы карта идентификационных данных была действительна через запрос. Таким образом, я мог использовать МОК для введения моего собственного IUnitOfWork к моим классам репозитория прозрачно, и я мог использовать тот же экземпляр, чтобы запросить и затем обновить мои объекты.
Так как я использую Единицу, я по ошибке использовал PerThreadLifeTimeManager. Я скоро понял, что модель потоков ASP.NET не поддерживает то, чего я хочу достигнуть. В основном это использует пул потоков и перерабатывает потоки, и это означает, что я получаю один UnitOfWork на поток!! Однако то, что я хотел, было одной единицей работы на веб-запрос.
Немного поиска с помощью Google дало мне это большое сообщение. Это было точно, что я хотел; за исключением части единицы, которой было довольно легко достигнуть.
Это - моя реализация для PerCallContextLifeTimeManager для единицы:
public class PerCallContextLifeTimeManager : LifetimeManager
{
private const string Key = "SingletonPerCallContext";
public override object GetValue()
{
return CallContext.GetData(Key);
}
public override void SetValue(object newValue)
{
CallContext.SetData(Key, newValue);
}
public override void RemoveValue()
{
}
}
И конечно я использую это для регистрации моей единицы работы в коде, подобном этому:
unityContainer
.RegisterType(
new PerCallContextLifeTimeManager(),
new InjectionConstructor());
Надежда это экономит кому-то немного времени.
Отличное решение, но каждый экземпляр LifetimeManager должен использовать уникальный ключ, а не константу:
private string _key = string.Format("PerCallContextLifeTimeManager_{0}", Guid.NewGuid());
В противном случае, если у вас есть более одного объекта, зарегистрированного в PerCallContextLifeTimeManager, они используют один и тот же ключ для доступа к CallContext, и вы выиграли Я не верну ожидаемый объект.
Также стоит реализовать RemoveValue, чтобы гарантировать очистку объектов:
public override void RemoveValue()
{
CallContext.FreeNamedDataSlot(_key);
}