How to provide ASP.NET MVC2 master pages with a model indepdent of the controller - asp.net-mvc-2

I'm using strongly typed views and autofac for Dependency Injection under ASP.NET MVC2 and I'm trying to get a common dynamic header via dependency injection. I.e. i want this to happen without the view having to be away of this content even existing and i was hoping to avoid static discovery of the container and manual resolution, but I can't find a way to easily inject the master or a partial view included in the master via either ctor or property injection.
I can't imagine this is an uncommon task, but all I can find in terms of methods is Controller subclassing to stuff data into untyped ViewData, subclassing ViewModels to stuff master data into the model, or static resolution, all of which I'd prefer not to use. What am I overlooking?
EDIT: As has been pointed out DI into master pages is fighting the framework. So my question is badly framed: I don't really care about DI into master pages, but I have a dynamic element in the chrome of the site, i.e. the master page. Providing it with a model shouldn't be the responsibility of each controller using that master, as it is request context, not controller context specific. I fully admit that injection directly into master pages is inappropriate. If i could register a separate master controller to be invoked in addition, that would be even better. Is that possible? Given this task of providing the master with a model independent of the controller, what is the framework appropriate approach? Or does shared content in MVC require that each Controller has to know about that content?

You could use child actions.
Controller:
public class MyHeaderController: Controller
{
private readony IRepository _repository;
public MyHeaderController(IRepository repository)
{
_repository = repository;
}
[ChildActionOnly]
public ActionResult Index()
{
var model = _repository.GetSomeModel();
return PartialView(model);
}
}
And somewhere in your master page include it:
<div><%= Html.Action("Index", "MyHeader") %></div>

Your problems stem from confusing the term Dependency Injection, and fighting how the ASP.NET MVC framework works.
Also, you are using the term Dependency Injection in the wrong context. You are trying to use a hammer as a chisel.
MasterPages and views in ASP.NET MVC are intended to be used as templates. As stated in the other answer, child actions will solve your problem.
For future reference:
Dependency Injection refers to a means to configure what parameters to inject into class constructors, and have this done for you automatically, overriding some of the frameworks defaults. The purpose for this is to decouple components, so that they become more reusable, more testable, more unitary, amongst other good things.
DI refers to, and solves, a code issue, not a UI issue.
What you are trying to do is simply not possible. Ie, inject via constructors and properties a "dependency" into a masterpage. Again, MasterPages are intended by ASP.NET MVC to be used as just templates. They have no code behind class to instantiate via a constructor that would allow dependencies to be injected into it.
In other words, you are fighting the framework, which means you don't understand it.
If this sounds like nitpicking, I think this has to be highlighted as otherwise, you are confusing yourself and others who read this thread in the future.

Related

MVVM dependency injection with Unity for layered view models

I have searched extensively and have been unable to find any good guidance on how to properly design an application using dependency injection that has multiple layers of view models.
What is the best way to implement dependency injection using something like Unity when you have view models that will need to create view models that will need to create yet other view models?
For example, let's say I have an application with a MainViewModel where I want to be able to show a bunch of different types of data in a tabbed interface a la Visual Studio.
I execute a command to open a collection of User objects using a view model called UsersViewModel. This view model takes a repository IUserRepository in its constructor. A GetAll method on IUserRepository is invoked to get a collection of User objects which are displayed in a grid in the view.
If the details for a specific User object need to be edited, I need to create a UserViewModel that also takes an instance of IUserRepository and the ID of the particular User object in its constructor. A FindById method on IUserRepository is invoked to get the specific User object.
I need to show the User details in a separate tab in the main view. I have a requirement to be able to view/edit the details for multiple User objects simultaneously, so I can't just open the details modally. As such, the UserViewModel needs to be able to persist its own changes since the UsersViewModel could be closed before a particular UserViewModel is saved.
So what is the best way to resolve the UserViewModel instances for this scenario? I could pass an instance of IUnityContainer into UsersViewModel and then use that to resolve them, but from what I've read, that is a bad idea. How else can it be done?
I have set up a MVVM application with Autofac and MEF to solve the problem you are talking about. To make a long story short, I have created a service interface IViewModelProvider which serves ViewModels for arbitrary models. The implementation of this service provides a cache for all ViewModels and creates ViewModels for models if no ViewModels of the requested ViewModel type for a particular model can be found.
The ViewModelProvider is kind of it's own IoC container, which reflects all loaded assemblies at initialization and then resolves the dependencies at runtime. The ViewModelProvider registers an instance of itself for the service IViewModelProvider and thus can pass itself to the ViewModelswhich require the ability to instantiate new ViewModels.
I am very happy with this solution, as I feel like having a neat separation of concerns here. The global ViewModel cache is awesome, because it saves resources and you can actually compare ViewModels for equality, which I come across quite often.
This solution can be simplified by using the same IoC container as for the UI, as you have pointed in your question. I agree that it is not a good idea to pass the IUnityContainer to the ViewModels directly. I can't see anything wrong about using the container for resolving the ViewModels, though. I would recommend to build a simple service, which caches ViewModel instances and creates new ViewModels by using the IUnityContainer.
The following code is pseudo code, mixing a bit of MEF with a bit of Autofac syntax, but I think it get's clear what it's about:
An interface for getting the ViewModels:
public interface IViewModelProvider
{
T GetViewModel<T>(object model);
}
An implementation which imports the Unity container and uses it for resolving ViewModels which have not been cached already. The ViewModelCache is something like an advanced dictionary you have to build yourself.
[Export(typeof(IViewModelProvider))]
public class ViewModelProvider : IViewModelProvider
{
private IUnityContainer _container;
private ViewModelCache _viewModelCache;
[ImportingConstructor]
public ViewModelProvider(IUnityContainer container)
{
_container = container;
}
public T GetViewModel<T>(object model)
{
if (_viewModelCache.Contains<T>(model))
return _viewModelCache.Get<T>(Model);
var viewModel = _container.Resolve<T>();
viewModel.Model = model;
_viewModelcache.Cache(viewModel);
return viewModel;
}
}
then this service can be injected into your ViewModels and the ViewModels can create their own children ViewModels and don't have to care about whether these already exist because or need to be created.
Hope this helps. It's a broad topic, so please ask if you have any particular questions.

Repository and IoC Patterns

Previously I asked this question and on a answer I got this comment:
This works, however injecting the container to a part, as far as I know, is not a "normal" use-case of MEF.
In my web app I have a few repositories that, of course, retrieve entities from the DB. To make them as loosely coupled as possible I'm making them return interfaces (eg IUser, IBill, IBlaBlaBla...) and the repository project only references the library project (that contains the interfaces). I use MEF composition capabilities to tie it all up...
Since the repository must have a concrete object to fill with info it got from the DB and the only the Container is aware of which concrete class maps to a specific interface I think that the repository MUST have reference to the container so it can call the "Resolve()", get a new instance and do his job, but that apparently is a mistake.
Can anyone tell me why and what approach would be better?
PS: I don't know if it's relevant but I'm using DDD...
I think the flaw in your design that lead to this problem is the use of interfaces to hide entities behind. Since entities are your core concept in your domain, there should be no use in hiding them behind an abstraction. Let's put it differently: do you ever have a different implementation of IUser?
In other words, ditch the IUser, IBill, etc. interface and let your repositories and business commands depend directly on your aggregate entities.

Best practice for creating a details view model (in Xaml)

I'm creating a windows 8 application (but I suspect that any one using Xaml can help me). It basically boils down to: a page with a list of products on it, clicking on a product opens a details page.
In my composition root I resolve the view model for the first page, and set the data context appropriately, but I'm not sure what the best practice is for passing a view model to page 2 when the user selects a product.
As far as I can tell I have the following options:-
The first viewmodel requires an abstract factory capable of creating
a view model for page 2 with a .create(product) method, this would be passed in to the first view models constructor
Have the second view model implement an interface with an product property allowing me to use property injection, and pass the second view model as a parameter to the first viewmodel.
Create a service locator which I know is considered by many to be an anti-pattern.
I'm at a bit of a loss, but I suspect the abstract factory is the right way to go, I want to get this right as the object graph is actually this (product->Step->Instruction), so any re-work could take quite a bit of time, but it basically means that my view model if I went down the abstract factory route would take three abstract factories, and the service for getting the initial list of products (and then is this a code smell given how many parameter it has!).
In the situation where you want to resolve the view-model in runtime (from code) factory is the way to go.
To make it easier I would also consider using some DI framework. I believe there won't be many of them for WinRT but autofac is supposed to work with metro.
Dependency Injection might be the way to do it if you are building something big. Personally I usually just pass the parameters in the Navigate() call and initialize the view model using these parameters in the OnNavigatedTo handler.

MEF and MVC - a few pointers please :)

What I am trying to do is inject a component into my MVC app and make use of it from the controllers.
Currently I am not trying to use MEF for the actual controllers, but i want to import components e.g. A loggin component into the MVC app.
Where is the best place to do this?
Currently I have, directly in the controller, put my compose parts code and ILogger property, but I get the feeling this is not the best way. Seems like I should only need to call Compose once in the application.
So should it be in the global asax file that I do the compose?
If so, how do I get a handle on ILogger from my controllers? Should I have a "base" controller, where i inject ILogger into the constructor and inherit every standard controller from?
Hope that makes sense - I'm just struggling a bit with the structure of my code.
Thx
I use Log4Net and inject the logger into each controller. I dont think its a big hit when you use injection. Take a look at Ninject. It has both an MVC implementation and a logging module. The modules are loaded once in the global, then it injects the controllers. Basic DI, but do you really need more? If you create a base controller you will still have to create a ctor in each controller that can be injected.
You might create a base controller with the logging, then use property injection. I have never done this, but if all controllers use the same base it should work fine.

MVVM - Using simple model as it's own view model is a bad practice?

Guess we have simple model, e.g. let it be a Person { Name, Age }.
Now we want to display a list of persons.
Persons are read-only
We don't need to edit them
We don't need any additional stuff like presentation properties, etc.
Now question is if it is a good practice do not create PersonViewModel class that will probably be a copy of model class or will delegate all its properties? Is it a good idea to simply bind listbox to list of persons, not to their view models? It looks DRY enough, but what about idea of MVVM?
I have no issue with bypassing the VM and using the M directly in the View. Sometimes the models are so small and static that loading them into a wrapping VM is wasteful.
I've created standalone ViewModels, but generally not standalone models. The reason for this is DataBinding -- most POCOs don't implement the INotifyPropertyChanged interface and adding them in to make them pseudo-Models seems to defeat the purpose of re-using a simple class AND respecting the MVVM pattern.
Now, if you KNOW you're never going to be editing them, it may not be a bad idea. A VM with simple property redirects seems a bit pointless to me.
As far as I'm concerned, if you implement INotifyPropertyChanged, then it becomes a ViewModel, and you can bind to it. :) When I wrote SoapBox Core which is all MVVM, I took the approach that everything is a ViewModel. The only Model objects were classes from third party libraries that I brought in and wrapped in a ViewModel of my own.
I wouldn’t create a ViewModel for the Person business object when the ViewModel doesn’t introduce new required functionality.
You might be interested that there is a second approach in the MVVM community: Create a ViewModel per View and not per Business Object.
Sample applications that follow this approach can be found on the WPF Application Framework (WAF) website.