Я реализовал шаблон Unit of Work/Repository, как описано здесь, но я также использую autofac и внедрение конструктора, поэтому я зарегистрировал UnitOfWork и Класс DbContext (PsyProfContext) выглядит следующим образом:
builder.Register(context => new PsyProfContext()).InstancePerHttpRequest();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerHttpRequest();
И все отлично работает!
За исключением одного: я также использую enterprise блок ведения журнала библиотеки, и я реализовал CustomTraceListener, который использует Entity Framework для записи записи журнала в базу данных.
Мой контроллер выглядит так (он пуст, потому что в данный момент я просто пытался проверить, все ли работает (IoC, ведение журнала, структура сущностей)):
public class HomeController : Controller
{
private readonly UnitOfWork unitOfWork;
public HomeController(IUnitOfWork unitOfWork)
{
this.unitOfWork = (UnitOfWork) unitOfWork;
}
//
// GET: /Home/
public ActionResult Index()
{
throw new HttpException();
return View();
}
protected override void Dispose(bool disposing)
{
unitOfWork.Dispose();
base.Dispose(disposing);
}
}
И в методе Write класса CustomTraceListener я попытался разрешить UnitOfWork:
DependencyResolver.Current.GetService<IUnitOfWork>() as UnitOfWork;
Но я получаю экземпляр, который уже утилизирован! поэтому я поставил несколько точек останова и обнаружил, что метод Dispose контроллера вызывается перед методом Write класса CustomTraceListener, поэтому в итоге я не нашел другого решения, кроме прямого использования DbContext (PsyProfContext):
public override void Write(object o)
{
using (var conext = new PsyProfContext())
{
var customLogEntry = o as CustomLogEntry;
if (customLogEntry != null)
{
var logEntry = new LogEntry
{
//a bunch of properties
};
conext.Exceptions.Add(logEntry);
conext.SaveChanges();
}
}
}
Но мне не нравится это решение! Какой смысл использовать шаблон UnitOfWork и Repository, если вы напрямую обращаетесь к объекту DbContext. Или какой смысл использовать DI в проекте, если в некоторых случаях вы создаете зарегистрированный объект вручную.
Вот я и хотел услышать ваше мнение, как поступать в подобных ситуациях? Моя текущая реализация в порядке, или она определенно неверна, и я должен подумать о другой.
Любая помощь будет принята с благодарностью, и любые идеи приветствуются!