We are developing what is becoming a sizable ASP.NET MVC project and a code smell is starting to raise its head.
Every controller has 5 or more dependencies, some of these dependencies are only used for 1 of the action methods on the controller but obviously are created for every instance of the controller.
I'm struggling to think of a good way to reduce the number of objects that are created needlessly for 90% of calls.
Here are a few ideas I'm toying around with:
Splitting the controllers down into smaller, more targeted ones.
Currently we have roughly a controller per domain entity, this has led to nice looking URLs which we would like to emulate, meaning we would end up with a much more complicated routing scheme.
Passing in an interface wrapping the IoC container.
This would mean the objects would only be created when they were explicitly required. However, this just seems like putting lipstick on a pig.
Extending the framework in some way to achieve some crazy combination of the two.
I feel that others must have come across this same problem; so how did you solve this or did you just live with it because it isn't really that big a problem in your eyes?
I've been pondering solutions to this very problem, and this is what I've come up with:
Inject your dependencies into your controller actions directly, instead of into the controller constructor. This way you are only injecting what you need to.
I've literally just whipped this up, so its slightly naive and not tested in anger, but I intend to implement this asap to try it out. Suggestions welcome!
Its of course StructureMap specific, but you could easily use a different container.
in global.asax:
protected void Application_Start()
{
ControllerBuilder.Current.SetControllerFactory(
new StructureMapControllerFactory());
}
here is structuremapcontrollerfactory:
public class StructureMapControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(Type controllerType)
{
try
{
var controller =
ObjectFactory.GetInstance(controllerType) as Controller;
controller.ActionInvoker =
new StructureMapControllerActionInvoker();
return controller;
}
catch (StructureMapException)
{
System.Diagnostics.Debug.WriteLine(ObjectFactory.WhatDoIHave());
throw;
}
}
}
and structuremapcontrolleractioninvoker (could do with being a bit more intelligent)
public class StructureMapControllerActionInvoker : ControllerActionInvoker
{
protected override object GetParameterValue(
ControllerContext controllerContext,
ParameterDescriptor parameterDescriptor)
{
object parameterValue;
try
{
parameterValue = base.GetParameterValue(
controllerContext, parameterDescriptor);
}
catch (Exception e)
{
parameterValue =
ObjectFactory.TryGetInstance(
parameterDescriptor.ParameterType);
if (parameterValue == null)
throw e;
}
return parameterValue;
}
}
There is the concept of "service locator" that has been added to works like Prism. It has the advantage of reducing that overhead.
But, as you say, it's just hiding things under the carpet. The dependencies do not go away, and you just made them less visible, which goes against one of the goals of using DI (clearly stating what you depend on), so I'd be careful not to overuse it.
Maybe you'd be better served by delegating some of the work. If there is some way you were intending to re-partition your controller, you might just want to create that class and make your controller obtain an instance of it through DI.
It will not reduce the creation cost, since the dependencies would still be resolved at creation time, but at least you'd isolate those dependencies by functionality and keep your routing scheme simple.
I would consider separately the problem of dependencies and creation of dependent objects. The dependency is simply the fact that the controller source code references a certain type. This has a cost in code complexity, but no runtime cost to speak of. The instantiation of the object, on the other hand, has a runtime cost.
The only way to reduce the number of code dependencies is to break up the controllers. Anything else is just making the dependencies a bit prettier, as you say. But making the dependencies (as opposed to instantiation of the dependent objects, which I'll cover in a second) prettier may well be enough of a solution that you don't need to break up the controllers. So IoC is a decent solution for this, I think.
Re: creating the objects, you write, "...some of these dependencies are only used for 1 of the action methods on the controller but obviously are created for every instance of the controller." This strikes me as the real problem, rather than the dependency, per se. Because it's only going to get worse as your project expands. You can fix this problem by changing the instantiation of the objects so that it does not happen until they are needed. One way would be to use properties with lazy instantiation. Another way would be to use arguments to your action methods with model binders which instantiate the objects you need. Yet another way would be to write functions which return the instances you need. It's hard to say which way is best without knowing the purpose of the objects you're using.
Your controllers may be becoming too "Fat". I suggest creating an application tier which sit beneath your controllers. The application tier can encapsulate a lot of the orchestration going on inside your controller actions and is much more testable. It will also help you organize your code without the constraints of designated action methods.
Using ServiceLocation will also help (and yes, I'm essentially reiterating Denis Troller's answer- which probably isn't good but I did vote his answer up).
Related
I have this legacy ASP.NET webapp that's mostly been transitioned to MVC. Code testability is generally bad, as it happens a lot to legacy apps: responsibilities are in a jumble, tight coupling prevails, that sort of thing.
I've been refactoring the app for a couple weeks to improve testability, doing my best to abide by SOLID, and I've come to this point where I need to pass HttpContext or HttpResponse and the like to a method in the HttpModule. Now, obviously the HttpModules can grab a copy of the HttpApplication and just pass that everywhere - which is how it is atm - but I would rather not grant access to such a large root object to a dependency.
Because some of our IHttpModules are initialized before the MVC even comes into play, I've had problems with using an IoC container to inject HttpContextBase or HttpResponseBase into constructors of various helpers that the modules use. I thus have to either pass the HttpContextBase to methods of said helpers - which is taxing to use and feels somewhat wrong - or create something like this:
public class HttpContextProvider : IHttpContextProvider {
// ... ctor
public HttpContextBase GetContext() { return HttpContext.Current; }
}
I would then inject an instance implementing IHttpContextProvider into a helper and call .GetContext() on it later as needed.
Intuitively, I feel like I might be doing something wrong, but cannot really get a handle on what it could be. This whole refactoring is complex enough - and the bus factor in the team is low enough - that I'm hesitant to request too much of the lead dev's time for this issue, which could almost be seen as academic from a practical standpoint.
I can suggest different options
try to register this objects in IoC, but to fix the problem (that class is initialized before it's dependences can be resolved) just use Lazy< T>, most IoC support them, check if yours is
Introducing providers as in your example, but I'll suggest it to return not HttpContext (or HttpResponse), but exactly what you need from this classes, it would be easier in tests to mock this behaviour (you maybe even don't need to construct context there at all) and also it will hide all complex stuff of HttpContext that isn't used
The second option will work only if you use this objects in similar way each time - so that you can replace it with 2-3 methods of ISmthProvider. If you use objects always differently maybe it will be better to combine both approaches and extract the most popular usages into some service and in other places path Lazy< HttpContextBase> to constructor
In my opinion it's better not to pass HttpContext/HttpResponse directly as it giving access for too much stuff and later people can make a mess of it (using it without thinking as it's already there) as a result it would be difficult to test and to make refactoring later.
I am fairly new to Dependency Injection, and I wrote a great little app that worked exactly like Mark Seemann told me it would and the world was great. I even added some extra complexity to it just to see if I could handle that using DI. And I could, happy days.
Then I took it to a real world application and spent a long time scratching my head. Mark tells me that I am not allowed to use the 'new' keyword to instantiate objects, and I should instead let the IoC do this for me.
However, say that I have a repository and I want it to be able to return me a list of things, thusly:
public interface IThingRepository
{
public IEnumerable<IThing> GetThings();
}
Surely at least one implementation of this interface will have to instantiate some Thing's? And it doesn't seem so bad being allowing ThingRepository to new up some Things as they are related anyway.
I could instead pass round a POCO instead, but at some point I'm going to have to convert the POCO in to a business object, which would require me to new something up.
This situation seems to occur every time I want a number of things which is not knowable in the Composition Root (ie we only find out this information later - for example when querying the database).
Does anyone know what the best practice is in these kinds of situations?
In addition to Steven's answer, I think it is ok for a specific factory to new up it's specific matching-implementation that it was created for.
Update
Also, check this answer, specifically the comments, which say something about new-ing up instances.
Example:
public interface IContext {
T GetById<T>(int id);
}
public interface IContextFactory {
IContext Create();
}
public class EntityContext : DbContext, IContext {
public T GetById<T>(int id) {
var entity = ...; // Retrieve from db
return entity;
}
}
public class EntityContextFactory : IContextFactory {
public IContext Create() {
// I think this is ok, since the factory was specifically created
// to return the matching implementation of IContext.
return new EntityContext();
}
}
Mark tells me that I am not allowed to use the 'new' keyword to instantiate objects
That's not what Mark Seemann tells you, or what he means. You must make the clear separation between services (controlled by your composition root) at one side and primitives, entities, DTOs, view models and messages on the other side. Services are injectables and all other types are newables. You should only prevent using new on service types. It would be silly to prevent newing up strings for instance.
Since in your example the service is a repository, it seems reasonable to assume that the repository returns domain objects. Domain objects are newables and there's no reason not to new them manually.
Thanks for the answers everybody, they led me to the following conclusions.
Mark makes a distinction between stable and unstable dependencies in the book I am reading ( "Dependency injection in .NET"). Stable dependencies (eg Strings) can be created at will. Unstable dependencies should be moved behind a seam / interface.
A dependency is anything that is in a different assembly from the one that we are writing.
An unstable dependency is any of the following
It requires a run time environment to be set up such as a database, web server, maybe even the file system (otherwise it won't be extensible or testable, and it means we couldn't do late binding if we wanted to)
It doesn't exist yet (otherwise we can't do parallel development)
It requires something that isn't installed on all machines (otherwise it can cause test difficulties)
It contains non deterministic behaviour (otherwise impossible to test well)
So this is all well and good.
However, I often hide things behind seams within the same assembly. I find this extremely helpful for testing. For example if I am doing a complex calculation it is impossible to test the entire calculation well in one go. If I split the calculation up into lots of smaller classes and hide these behind seams, then I can easily inject any arbirtary intermediate results into a calculating class.
So, having had a good old think about it, these are my conclusions:
It is always OK to create a stable dependency
You should never create unstable dependencies directly
It can be useful to use seams within an assembly, particularly to break up big classes and make them more easily testable.
And in answer to my original question, it is ok to instatiate a concrete object from a concrete factory.
Given this example of an MVC controller; psuedo code...
PostController
{
private IGetPost _getPost;
private ICreatePost _createPost;
private IDeletePost _deletePost;
private IUpdatePost _updatePost;
public ActionResult Get()
{
return _getPost();
}
public ActionResult Create(post)
{
return _createPost(post);
}
public ActionResult Update(posts)
{
return _updatePost(post);
}
public ActionResult Delete(post)
{
return _deletePost(post);
}
}
The question I have is that if any one of the actions on the controller is called, all the dependencies of the controller have instances created for them, which seems like a performance buzzkill. Is there a better way to do this? The only thought I had was to create 4 different controllers each with only a single action, but that seems like overkill. I also thought of calling the DependencyResolver directly in each action, but I am unsure of what the implications for unit testability will be if I do that.
Why is it a performance buzzkill? Have you measured this to be the case? While there's overhead in determining what implementations map to what interfaces, most dependency injection (DI) containers worth their salt will do this mapping once (and usually create compiled code on the fly so that the lookup is as quick as possible) to create the mappings.
It's then just a matter of creating the objects, which would be no different than if you were to use the new keyword.
For general cases, this isn't going to be a performance hit. Considering this is a web application, if you were getting Stack Overflow levels of traffic, then it very well could be an impediment to scaling; each of these operations is cheap, but when multiplied by a factor of millions, in aggregate, it's very expensive, and usually, these are the types of things that could lead to resource contentions, etc.
Assuming that this isn't the case (Stack Overflow levels of traffic), where you very well could be facing a performance issue is in the implementations of the constructors.
If the implementation of those four interfaces (or any number of them) is costly, that's not a function of DI, it's a function of your code and that's something you will get more benefit from optimizing.
The only place where tweaking the dependency injection might be beneficial would be if the construction one or more of those implementations had high overheads, and you had your DI container create one instance for all interface implementations instead of one instance per interface implementation. However, you should only look into lifetime management through the DI layer when you've determined that option is available to you (meaning, having one instance of that class to service all requests is viable; is it thread-safe? Does it hold onto any resources for a very long time? etc.)
If you're truly concerned about this and the above doesn't apply or isn't an option, then yes, you could create a number of smaller controllers, and that might make sense for other reasons; if the actions you are performing are not logically related to each other, they probably should be in separate controllers.
However, looking at the actions you have, it would seem that the logical divide you have is correct.
Long story short, don't try to optimize for performance in places you haven't measured it to be a factor.
That said, whatever you do, do not resolve dependencies inside of your class. If you do, you lose all the benefits of DI, and are tightly binding your class to a DI container (and possibly killing testability while at it).
I'm not sure the performance will really be a problem unless you have a really ridiculous number of dependencies. Either way, it's a good exercise to look at your architecture.
The way we do this is to abstract service level calls out to an external class, called a handler. This is from inspiration from Project Silk. This way, not only are you slimming down your controllers and making them much more manageable, but it avoids this kind of dependency build up.
In this case, you'd have the one controller which, for each action, simply resolves a handler and its dependencies, and executes it. Handlers are defined as small classes with very few (one is common) methods.
class MyController : BaseController
{
public ActionResult Get(int id)
{
return Using<GetItemHandler>().Execute(id);
}
}
class GetItemHandler
{
private IDependency _myDep;
public GetItemHandler(IDependency dep)
{
_myDep = dep;
}
public Execute(int id)
{
return _myDep.Get(id);
}
}
Note that the way this works is that the Using<T>() method (defined in the BaseController) uses the IoC container to resolve the handler, thus grabbing all it's dependencies. Then we can just use it as normal. I think this pattern really helps to separate out responsibilities and keep your classes and controllers nice and lean.
I use DI quite a lot in my projects and I'm fairly comfortable with the concept, however there's one aspect which I'm not quite sure about.
So a common use-case for me is to have an ASP.NET MVC Controller where I list the controller's dependencies in the constructor's parameter list, obviously these are passed in when the Controller is constructed by the DI Container, I then assign these to readonly private variables to be later consumed by Actions within the Controller.
Now, my concern is that if I only use an injected dependency (let's say an IMemberRepository) within one Action (and let's say there are 5 other Actions), should I list this as a dependency in the ctor, or should I call Container.Resolve<IMemberRepository>() within the one Action where it's used?
I have to say, I do like listing all my dependencies in the ctor, and I don't particularly like Container.Resolve<>() strewn throughout my code, but, going on the example above, there's no point in getting the DI container to instantiate an IMemberRepository if it's going to be used!
You should never call Container.Resolve from within your application code. This is the Service Locator pattern, and is considered an anti-pattern. Not injecting all dependencies through the constructor means you are hiding the used dependencies, which makes it less clear what depenencies a class has and makes it harder to test that class.
You are concerned about performance when dependencies are injected but not used, but this is normally not an issue, since construction of objects is usually very fast (since all those objects should do during construction is storing all incoming dependencies in private fields). When construction is proven to be too slow for a certaintype, there are other solutions, such as wrapping that dependency into a proxy that lazily initializes that dependency.
If you find that your class gets too many constructor arguments, it is a sign that it has too many responsibilities; it is doing too much. Try to repair this flaw in the class's design instead of falling back to Container.Resolve. For instance, extract a group of dependencies with the classes logic into a single new type and inject that as dependency.
There could be other problems with the design. When your controller depends directly on a repository dependency and you have business logic in the controller, you are missing an abstraction. You are missing a service layer. A good solution is the introduction of command handlers and query handlers.
I second what Steven has said.
If too many constructor arguments bug you then you could also opt for property injection. I favour this approach. There are some objects that, for some or other reason, are not injected into properties if they are not yet fully populated whereas they will be injected into the constructor.
I apply a guard to the dependency on properties to throw an exception if a dependency is null so that I know which dependency it is.
Hope that makes sense.
I would say that it depends on what you are wanting to do with DI.
The approach of using the injected dependencies as parameter in the constructor can end in a very long list of parameters.
This may be necessary for real Test Driven Development where you may want to mock the methods for your injected dependencies.
I personally think that it produces a lot of overhead as the DI Container always has to construct all dependencies, needed in an Action or not.
It is also to be considered that the usage of Actions and PartialViews produce a lot more constructions.
E.g.
public class HomeController : Controller
{
private IMemberRepository _memberRepo = null;
public HomeController(IMemberRepository repo)
{
_memberRepo = repo;
}
public ActionResult Index()
{
MyViewModel viewModel = _memberRepo.DoSomething();
return View(viewModel);
}
[ChildActionOnly]
public PartialViewResult SomePartialAction()
{
return PartialView();
}
}
Where the view Index.cshtml calls the partial view SomePartialAction() by #Html.Action("SomePartialAction").
In this case the constructor of the controller is called twice. Each time for each action. Therefore the DI container is also called twice.
So it really depends. For "hardcore" TDD you have to use the constructor. Otherwise I would resolve the dependencies where and when needed.
I have been reading though the code of the NerdDinner app and specifically the Repository Pattern...
I have one simple question though, regarding this block
public DinnersController()
: this(new DinnerRepository()) {
}
public DinnersController(IDinnerRepository repository) {
dinnerRepository = repository;
}
What if each Dinner also had, say, a Category... my question is
Would you also initialize the category Repository in the constructor of the class??
Im sure it would work but Im not sure if the correct way would be to initialize the repository inside the method that is going to use that repository or just in the constructor of the class??
I would appreciate some insight on this issue
Thanks.
What you're looking at here is actually not so much to do with the repository pattern, per se, and more to do with "dependency injection," where the outside things on which this class depends are "injected" from without, rather rather than instantiated within (by calling new Repository(), for example).
This specific example shows "constructor injection," where the dependencies are injected when the object is created. This is handy because you can always know that the object is in a particular state (that it has a repository implementation). You could just as easily use property injection, where you provide a public setter for assigning the repository or other dependency. This forfeits the stated advantage of constructor injection, and is somewhat less clear when examining the code, but an inversion-of-control container can handle the work of instantiating objects and injecting dependencies in the constructor and/or properties.
This fosters proper encapsulation and improves testability substantially.
The fact that you aren't instantiating collaborators within the class is what improves testability (you can isolate the behaviour of a class by injecting stub or mock instances when testing).
The key word here when it comes to the repository pattern is encapsulation. The repository pattern takes all that data access stuff and hides it from the classes consuming the repository. Even though an ORM might be hiding all the actual CRUD work, you're still bound to the ORM implementation. The repository can act as a facade or adapter -- offering an abstract interface for accessing objects.
So, when you take these concepts together, you have a controller class that does not handle data access itself and does not instantiate a repository to handle it. Rather the controller accepts an injected repository, and knows only the interface. What is the benefit? That you can change your data access entirely and never ever touch the controller.
Getting further to your question, the repository is a dependency, and it is being provided in the constructor for the reasons outlined above. If you have a further dependency on a CategoryRepository, then yes, by all means inject that in the constructor as well.
Alternatively, you can provide factory classes as dependencies -- again classes that implement some factory interface, but instead of the dependency itself, this is a class that knows how to create the dependency. Maybe you want a different IDinnerRepository for different situations. The factory could accept a parameter and return an implementation according to some logic, and since it will always be an IDinnerRepository, the controller needs be none the wiser about what that repository is actually doing.
To keep your code decoupled and your controllers easily testable you need to stick with dependency injection so either:
public DinnersController()
: this(new DinnerRepository(), new CategoryRepository()) {
}
or the less elegant
public DinnersController()
: this(new DinnerRepository(new CategoryRepository())) {
}
I would have my dinner categories in my dinner repository personally. But if they had to be seperate the id put them both in the ctor.
You'd want to pass it in to the constructor. That said, I probably wouldn't create any concrete class like it's being done there.
I'm not familiar with the NerdDinner app, but I think the preferred approach is to define an IDinnerRepository (and ICategoryRepository). If you code against interfaces and wanted to switch to say, an xml file, MySQL database or a web service you would not need to change your controller code.
Pushing this out just a little further, you can look at IoC containers like ninject. The gist of it is is that you map your IDinnerRepository to a concrete implementation application wide. Then whenever a controller is created, the concrete repository (or any other dependency you might need) is provided for you even though you're coding against an interface.
It depends on whether you will be testing your Controllers (, which you should be doing). Passing the repositories in by the constructor, and having them automatically injected by your IOC container, is combining convenience with straightforward testing. I would suggest putting all needed repositories in the constructor.
If you seem to have a lot of different repositories in your constructors, it might be a sign that your controller is trying to do too many unrelated things. Might; sometimes using multiple repositories is legitimate.
Edit in response to comment:
A lot of repositories in one controller constructor might be considered a bad code smell, but a bad smell is not something wrong; it is something to look at because there might be something wrong. If you determine that having these activities handled in the same controller makes for the highest overall simplicity in your solution, then do that, with as many repositories as you need in the constructor.
I can use myself as an example as to why many repositories in a controller is a bad smell. I tend to get too cute, trying to do too many things on a page or controller. I always get suspicious when I see myself putting a lot of repositories in the constructor, because I sometimes do try to cram too much into a controller. That doesn't mean it's necessarily bad. Or, maybe the code smell does indicate a deeper problem, but it not one that is too horrible, you can fix it right now, and maybe you won't ever fix it: not the end of the world.
Note: It can help minimize repositories when you have one repository per Aggregate root, rather than per Entity class.