Correct way to inject DbContext into a controller - asp.net-mvc

If I wish to inject my DbContext into one of my controllers as follows:
public class HomeController : Controller
{
MyDbContext _db;
public HomeController(MyDbContext db)
{
_db = db;
}
...
}
What is the correct way to configure this with Unity. The context would have to intantiated per request so PerRequestLifetimeManager seems like the natural choice. But from reading this documentation it seems that PerRequestLifetimeManager is advised against. The terms "thread-unsafe dependencies" make me nervous about using it as do the warning about it causing "bugs in the end user’s application code". The warnings seem to be very vague though so that it is not clear what the dangers actually are. Can anyone give examples of the kind of bugs that can occur from the use of PerRequestLifetimeManager? And if this lifetime manager is advised against, what would be a better way to inject the DbContext into my controllers?

Related

ASP.NET 5 / Core 1 Dependency Injection: Bad design or bad documentation?

I'm reading through the ASP.NET 5 docs and was choking on the chapter of dependency injection.
I am recommended to write my controllers like so:
public class MyController: Controller
{
private readonly MyService _myService;
public MyController(MyService myService)
{
_myService = myService;
}
public IActionResult Index()
{
// use _myService
}
}
The short and direct version is discouraged:
public class MyController : Controller
{
public IActionResult Index()
{
var myService = (MyService)HttpContext.RequestServices.GetService(typeof(MyService));
}
}
The given reason is because allegedly the recommended version...
[...] yields classes that are easier to test (see Testing) and are more loosely coupled.
The linked testing chapter doesn't shed any light on this weird statement.
I didn't look at the sources, but I assume whatever constructs the controller is using HttpContext.RequestServices.GetService itself to deliver the dependency? Clearly a test can setup a different implementation for testing, and clearly that is the whole point of a DI framework, right?
The colossus (MyService)HttpContext.RequestServices.GetService(typeof(MyService)) is bad enough, but a small helper could fix that (was a simple Get<MyService>() really so hard?).
But that this excessive clutter is recommended for basically every controller and more is disturbing.
It's all the more puzzling as there already is a Microsoft DI framework with a proper usage, MEF:
public class MyController : Controller
{
[Import]
private MyService _myService;
public IActionResult Index()
{
// use _myService
}
}
Why not at least just take that one? What's going on here?
This isn't a ASP.NET Core specific solution. This is how just about every DI framework works. The most common approach is to have all the dependencies of a controller as constructor parameters. This makes it clear what services the controller uses. There are multiple alternative solutions, but the basic idea stays the same and there are multiple pros and cons to them.
Clearly a test can setup a different implementation for testing, and clearly that is the whole point of a DI framework, right?
This line isn't clear to me. What do you think the 'whole point of a DI framework ' is? This line suggest you only use it so you can use a different implementation for testing.
But that this excessive clutter is recommended for basically every controller and more is disturbing.
Excessive clutter? What if I want to use MyService in two (or more) functions? Should I use this:
public class MyController : Controller
{
public IActionResult Index()
{
var myService = (MyService)HttpContext.RequestServices.GetService(typeof(MyService));
}
public IActionResult Index2()
{
var myService = (MyService)HttpContext.RequestServices.GetService(typeof(MyService));
}
}
Or should I opt for the solution where I set it up in the constructor? Seems like an obvious choice to me. In such a small example it may look like clutter, but add 10 lines of code to it and you'll barely notice a small constructor and some variable declarations.
You can use it while testing. It's a way to quickly grab something from the container when you need it, but it should certainly not be part of the actual code. You're simply hiding the dependency from sight.
At last you suggest property injection. This is a valid solution. But an often used argument against it is that it hides the dependency. If you define it as a parameter in the constructor you can't hide it. Besides, a lot of DI frameworks don't even have support for property or method injection because of this.
If you want to use MEF in your project you are free to do so. But it should, in my opinion, not be the default DI framework for ASP.NET. What's available right now is more than sufficient to do most tasks. If you need more functionality you can always use a different DI framework like StructureMap or AutoFac.
In the end it all comes down to what works for you. But stating this is either bad design or bad documentation is just wrong. You are of course free to prove me wrong on this. You could improve the ASP.NET documentation and/or would prove that the concept of inversion of control is wrong and suggest a better solution.

Using DbContext and DbSet instead of implementing repositories and unit of work

I have seen plenty of articles about implementing repositories and a unit of work. I have also seen articles about how doing this is just adding extra complexity, because the DbContext is already using the repository and unit of work pattern.
I will be refactoring an application that pretty much has a repository for each entity, and would like to remove as much complexity as possible.
Can anyone explain/provide links to articles/blogs/etc that explain how to use the DbContext instead of my own repositories?
Rob Conery's a smart guy, but I have to disagree with him on this one. Command/Query method he suggests just removes the query logic from the action (which is something, but not much). There's still no true abstraction. And, the base controller method is not great either. While the method of data access (here, an ORM) is abstracted to just one place in your code, making for somewhat easier changes in the future, it does nothing to abstract the API for working with that data layer, so it almost becomes pointless. The only thing it really saves you from is having to put private readonly AppContext context = new AppContext(); at the top of every controller. You could perhaps combine the two, but then you're still looking at having to modify every one of those query classes if your data layer changes.
I think the chief problem here is that everyone is trying to achieve something different. Rob's suggested approaches are geared towards staying DRY. Personally, my goal in abstracting the data layer is for the easy ability to switch out data access methods at a later point. Perhaps that's because I've been burned in the past by choose some method of getting at data that ended up not working out ideally in the long run. We can at least both agree, though, the traditional way of implementing repositories is a bad idea.
In truth, this is a problem with no true answer. To a certain extent you have to just do what works best for you and your application. The method I've settled on is somewhat akin to the repository pattern, I use generic methods instead of a generic class. Something like the following:
public class Repository : IRepository
{
protected readonly DbContext context;
public Repository(DbContext context)
{
this.context = context;
}
public IEnumerable<TEntity> GetAll<TEntity>()
{
var dbSet = context.Set<TEntity>;
return dbSet.ToList();
}
...
}
My actual class is much more complex than that, but that's enough to illustrate the main points. First, the context is injected. This is one area where I strongly disagree with Rob. Perhaps if you're playing fast and loose with your context you may not know "where it came from", but I use a dependency injection container which creates one instance per request of my context. In other words, I know exactly where it came from.
Second, because this is a standard old class with generic methods, I don't need to new up a bunch of them in my controller actions. I also don't have to define a separate repository class for each entity. I can simply inject this one dependency into my controller and roll:
public class FooController : Controller
{
private readonly IRepository repo;
public FooController(IRepository repo)
{
this.repo = repo;
}
...
}
Then, if I want to fetch some Foos, I just do:
repo.GetAll<Foo>();
Or if I want some Bars: repo.GetAll<Bar>().
Then, you can start to do really interesting things via generic constraints. Let's say I'd like to be able to pull out only items that are "published". All I need is an interface like:
public interface IPublishable
{
PublishStatus Status { get; }
DateTime? PublishDate { get; }
DateTime? ExpireDate { get; }
}
Then, I simply make whatever entities I want to be "publishable" implement this interface or inherit from an abstract class that implements it. Once that's all set up, I can now do something like the following in my repository:
public IEnumerable<TEntity> GetAllPublished<TEntity>()
where TEntity : IPublishable
{
var dbSet = context.Set<TEntity>();
return dbSet.Where(m =>
m.Status == PublishStatus.Published &&
m.PublishDate.HasValue && m.PublishDate.Value <= DateTime.Now &&
(!m.ExpireDate.HasValue || m.ExpireDate.Value > DateTime.Now)
).ToList();
}
Now, I have one method in one repository that can pull out just the published items for any entity that implements IPublishable. Code duplication is at a bare minimum, and more importantly, if I need to switch out the data access layer with something else like a differ ORM or even a Web API, I just have to change this one repository class. All the rest of my code happily chugs along as if nothing happened.

How to refer to Entity Framework DbContext from MVC business objects?

I'm starting a new ASP.NET MVC project. In my last project, one of the biggest code smells was how I passed around the Entity Framework DbContext, stored it in HttpContext.Current, called SaveChanges() in my rendering event, and did all manner of (probably unseemly) related things.
Suppose that my unit of work always corresponds to a web request. What is the right way to create a DbContext, share that context to a business library (e.g. an assembly outside the MVC project responsible for processing some workflow activities), share result models back to my controller, and persist any changes?
I'll be honest, I don't know much about dependency injection. It sounds like it should be related, but I don't see how it would get me a shared context instance between my controller and my business processes in an external assembly.
If I only needed it from controllers, it would be easy. I'd stick to HttpContext. But now HttpContext has spilled over to my external library. Do I just define an interface that returns the current DbContext, and base an implementation of that on HttpContext?
Hope that's clear what I'm asking, as I'm a little lost.
Dependency injection definitely sounds like what you are after here. My preference is ninject so below is a bit of an example of how I do this with EF.
Install Ninject.MVC3 (available on nuget)
Go to \app_start\NinjectWebCommon.cs (added by the above package) and add the following to the RegisterServices method
kernel.Bind<MyContext>().ToSelf().InRequestScope(); //binding in the context in request scope, this will let us use it in our controllers
Inside a controller consume the context as follows
public class MyController : ....{
private readonly MyContext _context;
public MyController(MyContext context){ _context = context; }
//Do stuff with _context in your actions
}
This is a really simple example for you to try there are plenty of better ways to structure this as your application grows (such as ninject modules) but this will demonstrate how DI works.
A few things to note, Always make sure you bind the context in requestscope (or more frequently) as DBContext has a nasty habit of growing quite bit if it sticks around too long.
In terms of sharing it with your external stuff that can be injected too, eg
public class MyExternalLogic{
public MyExternalLogic(MyContext context){....}
}
public class MyController : ....{
private readonly MyContext _context;
public MyController(MyContext context, MyExternalLogic logic){ _context = context; ...}
//Do stuff with _context in your actions
}
In the above the same instance of DbContext will be used for both MyController and MyExternalLogic. Ninject will handle the creation of both objects.
There are also a bunch of other DI containers available which will give you very similar experiences. I highly recommend DI as it helps a lot with unit test-ability as well.
For some more examples of how I use Ninject to structure my MVC apps check out some of my projects on github, such as https://github.com/lukemcgregor/StaticVoid.Blog

Dynamo IoC and Mvc

I'm trying out Dynamo IoC with the web extensions for Mvc, and I see they've done a great work creating a custom HttpApplication to derive your Global.asax from. However it seems I'm missing something.
I want to accomplish DI in my controllers, but I'm stuck with the usual "The controller must have a parameterless constructor" problem.
This is what I do in my global.asax (which derives from DynamoMvcAndWebApiApplication):
protected override void RegisterDependencies(Dynamo.Ioc.IIocContainer container)
{
container.Register<ILogger, FakeLogger>();
}
Then my controller:
public class HomeController : Controller
{
private readonly ILogger logger;
public HomeController(ILogger logger)
{
this.logger = logger;
}
public ActionResult Index()
{
logger.Log("test");
return View();
}
}
This gets me the "no parameterless constructor error". I thought the web extensions of Dynamo already took care of whatever was required to make DI work.
If I add a parameterless constructor it gets called, but then my ILogger will be null, and I'll get a NullReferenceException in my action method.
I thought about having to implement a ControllerFactory but I also thought that if it was mandatory they would have provided it along with all other stuff for MVC, so I think that I am misusing what is provided.
I'd like to know if anyone knows how to make DI work in this scenario. Thanks.
My best guess is that it is because you don't register the HomeController when registering the dependencies.
According to your example you don't.
I agree with MartinF. If you want your HomeController's dependencies to be resolved, you need to instantiate it by resolving it from your Dynamo container. Granted, I'm not seeing your resolve code, but I'm just guessing that's what's going on. I don't think it's a matter of "Dynamo doesn't fully integrate with MVC". Depending on how the container works, you may not even need to explicitly register HomeController with the container before trying to resolve it, but you DO need to ask the container to resolve it for you so that it may satisfy the dependencies. Just my guess based on the usage of other containers.
After a long digging and experimenting, it just seems that Dynamo doesn't fully integrate with MVC. I tried Ninject integration with MVC and it works fine, out of the box.
My guess is that Dynamo is just "not there yet", I'll keep checking on its updates in the future.

DDD and constructor explosion

I'm practicing DDD with ASP.NET MVC and come to a situation where my controllers have many dependencies on different services and repositories, and testing becomes very tedious.
In general, I have a service or repository for each aggregate root. Consider a page which will list a customer, along with it's orders and a dropdown of different packages and sellers. All of those types are aggregate roots. For this to work, I need a CustomerService, OrderService, PackageRepository and a UserRepository. Like this:
public class OrderController {
public OrderController(Customerservice customerService,
OrderService orderService, Repository<Package> packageRepository,
Repository<User> userRepository)
{
_customerService = customerService
..
}
}
Imagine the number of dependencies and constructor parameters required to render a more complex view.
Maybe I'm approaching my service layer wrong; I could have a CustomerService which takes care of all this, but my service constructor will then explode. I think I'm violating SRP too much.
I think I'm violating SRP too much.
Bingo.
I find that using a command processing layer makes my applications architecture cleaner and more consistent.
Basically, each service method becomes a command handler class (and the method parameters become a command class), and every query is also its own class.
This won't actually reduce your dependencies - your query will likely still require those same couple of services and repositories to provide the correct data; however, when using an IoC framework like Ninject or Spring it won't matter because they will inject what is needed up the whole chain - and testing should be much easier as a dependency on a specific query is easier to fill and test than a dependency on a service class with many marginally related methods.
Also, now the relationship between the Controller and its dependencies is clear, logic has been removed from the Controller, and the query and command classes are more focused on their individual responsibilities.
Yes, this does cause a bit of an explosion of classes and files. Employing proper Object Oriented Programming will tend to do that. But, frankly, what's easier to find/organize/manage - a function in a file of dozens of other semi-related functions or a single file in a directory of dozens of semi-related files. I think that latter hands down.
Code Better had a blog post recently that nearly matches my preferred way of organizing controllers and commands in an MVC app.
Well you can solve this issue easily by using the RenderAction. Just create separate controllers or introduce child actions in those controllers. Now in the main view call render actions with the required parameters. This will give you a nice composite view.
Why not have a service for this scenario to return a view model for you? That way you only have one dependency in the controller although your service may have the separate dependencies
the book dependency injection in .net suggests introducing "facade services" where you'd group related services together then inject the facade instead if you feel like you have too many constructor parameters.
Update: I finally had some available time, so I ended up finally creating an implementation for what I was talking about in my post below. My implementation is:
public class WindsorServiceFactory : IServiceFactory
{
protected IWindsorContainer _container;
public WindsorServiceFactory(IWindsorContainer windsorContainer)
{
_container = windsorContainer;
}
public ServiceType GetService<ServiceType>() where ServiceType : class
{
// Use windsor to resolve the service class. If the dependency can't be resolved throw an exception
try { return _container.Resolve<ServiceType>(); }
catch (ComponentNotFoundException) { throw new ServiceNotFoundException(typeof(ServiceType)); }
}
}
All that is needed now is to pass my IServiceFactory into my controller constructors, and I am now able to keep my constructors clean while still allowing easy (and flexible) unit tests. More details can be found at my blog blog if you are interested.
I have noticed the same issue creeping up in my MVC app, and your question got me thinking of how I want to handle this. As I'm using a command and query approach (where each action or query is a separate service class) my controllers are already getting out of hand, and will probably be even worse later on.
After thinking about this I think the route I am going to look at going is to create a SerivceFactory class, which would look like:
public class ServiceFactory
{
public ServiceFactory( UserService userService, CustomerService customerService, etc...)
{
// Code to set private service references here
}
public T GetService<T>(Type serviceType) where T : IService
{
// Determine if serviceType is a valid service type,
// and return the instantiated version of that service class
// otherwise throw error
}
}
Note that I wrote this up in Notepad++ off hand so I am pretty sure I got the generics part of the GetService method syntactically wrong , but that's the general idea. So then your controller will end up looking like this:
public class OrderController {
public OrderController(ServiceFactory factory) {
_factory = factory;
}
}
You would then have IoC instantiate your ServiceFactory instance, and everything should work as expected.
The good part about this is that if you realize that you have to use the ProductService class in your controller, you don't have to mess with controller's constructor at all, you only have to just call _factory.GetService() for your intended service in the action method.
Finally, this approach allows you to still mock services out (one of the big reasons for using IoC and passing them straight into the controller's constructor) by just creating a new ServiceFactory in your test code with the mocked services passed in (the rest left as null).
I think this will keep a good balance out the best world of flexibility and testability, and keeps service instantiation in one spot.
After typing this all out I'm actually excited to go home and implement this in my app :)

Resources