1

I have a web app and a windows service app.

The web app injects IPersonService into its MVC controllers.

The windows app also uses IPersonService.

The service takes 3 dependencies on IPersonRepo, IAddressRepo, IEmploymentRepo for example.

The implementations of the repositories take a DBContext for Entity Framework use.

In a web app I can register the DBContext as Bind<MyContext>().ToSelf().InRequestScope();

In the windows service its trickier. I could leave it so the DBContext is transient but that seems wrong.

So I thought I could make the services be the scope to determine the life cycyle of the DBContext but am completely unsure how I would go about that to make sure it worked well for a web app and windows service app.

Any help would be greatly appreciated

Jon
  • 38,814
  • 81
  • 233
  • 382
  • What's wrong with binding the DbContext in transient scope? In this way, the DbContext will live as long as the parent class it's being injected in. – Eric Eijkelenboom Apr 05 '13 at 08:41
  • I thought that in a web app if you have a 1 request and 1 service the context is created once for the 3 repos. Wouldn't you want the same for the sevices? – Jon Apr 05 '13 at 08:44
  • Will be updating http://stackoverflow.com/questions/15599325/looking-for-a-ninject-scope-that-behaves-like-inrequestscope/15604758#15604758 RSN You can create a plugin that registers itself as a service but I need to show the code in the answer – Ruben Bartelink Apr 05 '13 at 14:10
  • Exec summary If you have a root object for your handler and can stick to `ContextPreservingGet`s, then you can use DefinesNamedScope on that and have an INinjectHttpApplicationPlugin walk the tree to provide that to the InRequestScope mechanism. Sadly wont get to post today for sure. – Ruben Bartelink Apr 05 '13 at 14:13
  • OK, I couldnt stop - dumped my working code into http://stackoverflow.com/a/15836383/11635. If it comes close to answering your problem, it might be a good idea to close this in favor of the other question -- does it?? – Ruben Bartelink Apr 05 '13 at 14:23

1 Answers1

0

If it's important that all 3 repos use the same DbContext instance, you can do something like this:

var context = new DbContext(...);

Bind<IPersonRepo>().To<PersonRepo>().WithConstructorArgument("dbContext", context);
Bind<IAddressRepo>().To<AddressRepo>().WithConstructorArgument("dbContext", context);
Bind<IEmploymentRepo>().To<EmploymentRepo>().WithConstructorArgument("dbContext", context);

Like this the same context instance is shared between the repos.

If the repositories are not aware of each other's entities (and changes to these entities), you could simply inject a fresh instance of DbContext in each repo, by binding in transient scope (default behavior):

Bind<MyContext>().ToSelf(); 
Eric Eijkelenboom
  • 6,943
  • 2
  • 25
  • 29
  • Its not important but I thought that was the point of InRequestScope so I wanted to move that to the windows service – Jon Apr 05 '13 at 09:17
  • I see your point, but like you already mentioned, request scope is only available in web applications (where controller instances are managed by asp.net on request basis). In non-webapps, this scope is not applicable. – Eric Eijkelenboom Apr 05 '13 at 09:31
  • Which is why I wondered the scope be moved to the service so its responsible for the lifetime but not sure if thats correct – Jon Apr 05 '13 at 09:36
  • All instances that are injected into the Service class, directly or indirectly (further down the hierarchy), are automatically tied to the lifetime of the Service instance. This is perfectly fine in my opinion. Maybe I misunderstand your question? – Eric Eijkelenboom Apr 05 '13 at 09:56
  • I understand that, I believe its just harder to manage the lifetime of something when you dont have a request as the scope. – Jon Apr 05 '13 at 18:40