У меня есть приложение MVC 2.0, использующее Ninject.Web.Mvc2 и шаблон репозитория (построенный на основе структуры сущностей). Я пытаюсь создать новый ObjectContext, который будет жить только во время запроса. Я пытаюсь сделать это следующим образом:
protected override IKernel CreateKernel(){
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
return kernel;
}
protected override void OnApplicationStarted()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
После этого у меня закончились идеи для того, чтобы сохранить этот достаточно общий характер, поэтому я начал работать в BeginRequest:
protected void Application_BeginRequest()
{
string EntityConnectionString = ConfigurationManager.ConnectionStrings["Entities"].ConnectionString;
HttpContext.Current.Items.Add(_PerRequestContextObjectKey, new EntityFrameworkContextWrapper(EntityConnectionString));
this.Kernel.Bind<IUserRepository>().To<UserRepository>().WithConstructorArgument("ContextWrapper", HttpContext.Current.Items[_PerRequestContextObjectKey]);
}
Класс Wrapper - это просто общий объект для включения всего, что я хочу уничтожить в конце запроса. В этом конкретном случае я использую его для создания моего нового ObjectContext, а также реализую IDisposable, чтобы я мог сделать следующее:
protected void Application_EndRequest()
{
foreach (var Item in HttpContext.Current.Items)
{
if (Item.GetType() == typeof(IPerRequestLifetimeObjectWrapper))
{
(Item as IPerRequestLifetimeObjectWrapper).Dispose();
}
}
}
Я уверен, что это не самый красивый способ сделать это, но на данный момент я пытаюсь двигаться, так как я потратил так много времени, "изучая" все эти вещи.
Мой контроллер затем вводится так:
public class AdminUserController : Controller
{
// Mark for Ninject
[Inject] public IUserRepository _userRepo { get; set; }
public ViewResult Index( )
{
return View(_userRepo.Get);
}
public ViewResult Edit(Guid UserUID)
{
return View(_userRepo.GetById(UserUID));
}
}
и мой репозиторий тоже вводится:
[Inject]
public UserRepository(EntityFrameworkContextWrapper ContextWrapper )
// Mark for Ninject Dependency Injection
// Must receive Wrapper that contains active ObjectContext
{
_db = ContextWrapper.Entities; //Not actually named this, just easier for typing right now
}
Когда мой контроллер вызывает метод Get внутри моего объекта UserRepository в первый раз, он прекрасно работает. Если я нажму «обновить» (или я предполагаю, что постбэк тоже), _db - это Null. Когда я пытаюсь пройтись по отладчику, я обнаруживаю, что метод Controller Index () вызывается до вызова Application_BeginRequest (). Я думал, что у меня есть понимание «конвейера» (я привык называть вещи жизненным циклом страницы из WebForms), но теперь я немного растерялся. Может кто-нибудь уточнить, где в моем мозгу пересечены провода? Как я уже сказал, это, вероятно, не самый красивый метод, но у меня было всего около полутора недель, чтобы изучить MVC, DI с Ninject, Repository и Entity Framework, поэтому, пожалуйста, не думайте, что вы говорите плохо мне, если кажется, что я сломал что-то очень простое.