I'm using IoC container for dependency injection in Asp.Net MVC 3 and everything seems perfect until I started to write Action methods in my controller. What is the best way to create entity/model objects within the action methods? Sometimes models are retrieved from certain repository or service which are injected to the controller via the constructor, but its not the case with many other model objects in the system.
-
Can you give us more details? If some model objects don't come from a repository or service, then where do they come from? If you're creating new model objects, you can inject a model factory/builder as a dependency.. – MattDavey Dec 30 '11 at 15:44
-
Actually there is a controller which has several steps and most if not all actions generates different views with different models and set to view model. HtmlHelper needs an empty object set as model to use its extension methods to display a form to accept the data and this view's viewmodel has certain properties which are of specific entity type, say `SiteSettings` class. I'm not sure how to resolve both ViewModel and its dependency from within a Action method. – Mat J Dec 30 '11 at 16:31
-
I think the original question you asked is different from the question that you might have meant to ask. This question was about how to use the IOC container to resolve objects inside an action. Your real question sounds like it might be "How do I create a wizard in ASP.NET MVC?", and I *don't* think the right answer would involve using the IOC container within action methods. You might get a better solution if you ask a new question. – Paul Stovell Dec 30 '11 at 17:38
-
@PaulStovell Actually I'm having some teething problem with IoC. What I want is, there is this simple Action method which just creates a viewmodel which has an Settings Class as a property. I thought, I'll register these view models and other entities like `Settings` to the IoC along with others and it will create it for me, and thats what I did. From one of the answers below, I think I did it wrong. So, These View models and simple supporting classes which are used only by one or two methods of a controller can be directly created using `new`? And I'm not asking for help in creating a Wizard! – Mat J Dec 30 '11 at 18:36
2 Answers
You don't use a DI container to resolve action arguments. That's what a model binder is intended to do in ASP.NET MVC. And by the way your actions should be taking any domain models as arguments => they should be taking only view models. View models are classes that are specifically defined to meet the requirements of a given view.
So for some specific cases you have the possibility of writing a custom model binder which will be responsible for the instantiation and binding of your action arguments. As far as the instantiation of the model binder itself is concerned, in ASP.NET MVC 3 you could use a dependency resolver which could be used to inject dependencies into this model binder using your DI framework of choice.

- 1,023,142
- 271
- 3,287
- 2,928
-
Models or View Models, I'm not talking about posted data or parameters for that matter, So, how will we generate those data we need to pass to the view, like from a basic CRUD controller's `Create` action method. So, View models may be directly created? – Mat J Dec 30 '11 at 16:21
-
@Threecoins, I am not sure I understand what you are asking. The data you pass to the view is under the form of a view model. The view model is a class that you define and include the information this view will require. Your controller action will then query the repository to fetch the domain model and then map this domain model to a view model and pass the view model to the view. Maybe you can show some code to explain your problem a little better? – Darin Dimitrov Dec 30 '11 at 16:45
-
@DarinDimitrov If you could should an implementation of such a model binder with, say Autofac, then that'd be awesome. – Serj Sagan Feb 24 '16 at 22:44
An IOC container is best used for creating components; but it shouldn't be used for creating model objects. For example, this is good:
public ActionResult SignUp(string username, string password)
{
var user = new User(); // Your model object
user.Username = username; //...
_repository.Save(user);
return Redirect(...);
}
A model object shouldn't take any dependencies itself, so it shouldn't need to be resolved from an IOC container. The same applies to view models:
public ActionResult Show(int userId)
{
var user = _repository.Load<User>(userId);
var model = new ShowUserModel(user);
return View(model);
}
After creation a model/view model should be effectively read-only, so any information it needs should be passed in via the controller - it shouldn't take injected dependencies.
If you really, really did need to create components dynamically within the action, you can do it like this:
class HomeController : Controller
{
readonly Func<IFooService> _fooServiceFactory;
public HomeController(Func<IFooService> fooServiceFactory)
{
_fooServiceFactory = fooServiceFactory;
}
public ActionResult SomeAction()
{
var service = _fooServiceFactory(); // Resolves IFooService dynamically
service.DoStuff();
}
}
Any decent IOC container should be able to handle Func<T>
injection.

- 32,377
- 16
- 80
- 108
-
Why not just use normal constructor injection. Not that I've got anything against Func
. . . – Wyatt Barnett Dec 30 '11 at 17:33 -
I agree, ideally you would. But the question title reads "Using IoC to resolve model objects *in action methods*" (though I suspect there are better ways to achieve the real goal). – Paul Stovell Dec 30 '11 at 17:43
-
4A real world situation might be where you have half a dozen actions, only one of which requires an `IFooService`, and creating `IFooService` is expensive. In this situation, we can defer resolution of `IFooService` to the action, so that it isn't resolved for actions that don't require it. That said, it probably means there's a design problem with `IFooService` to start with :) – Paul Stovell Dec 30 '11 at 17:44
-
1Or a design problem in `IWhateverController` -- you might want to build the controller around the expensive service. – Wyatt Barnett Dec 30 '11 at 17:45