See this example of a really clean technique:
http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/29/how-we-do-mvc-view-models.aspx
: . "ASP.NET MVC In Action" CodeCampServer . IViewModelMapper {public ViewModel Map (); } . , IoC MapMedia Map. , , AutoMapper, , IViewModelMapper.
, ViewModel, .
UPDATE: , automapper, CodeCampServer. , ( ), .
public abstract class ViewModelMapper<Source, ViewModel> where Source: class, ViewModel: IViewModel
{
public abstract ViewModel Map(Source source);
}
public class ProductDetailsViewModel
{
public ProductViewModel Product { get; set; }
punlic IList<Language> AvailableProductLanguages { get; set; }
}
public class ProductDetailsViewMapper: ViewModelMapper<Product, ProductDetailsViewModel>
{
private ILanguageRepository languages;
public ProductDetailsViewMapper(ILanguageRepository languages)
{
this.languages = languages;
}
public override ProductDetailsViewModel Map(Product source)
{
var vm = new ProductDetailsViewModel();
AutoMapper.Map<Product, ProductDetailsViewModel>(product, vm);
vm.AvailableProductLanguages = languages.GetAppropriateFor(product);
}
}
public class ViewModelMapperActionFilter: ActionFilter
{
Type mapperType;
public ViewModelMapperActionFilter()
{
}
public ViewModelMapperActionFilter(Type mapperType)
{
}
public void OnActionExecuted(ControllerContext context)
{
var model = context.Result.ViewData.Model;
var mapperType = this.MapperType ?? this.GetMapperTypeFromContext(context);
var mapper = ServiceLocator.GetInstance(mapperType);
var method = mapperType.GetMethod("Map");
Check.Assert(method.GetArguments()[0].ArgumentType == model.GetType());
context.Result.ViewData.Model = method.Invoke(mapper, new[]{model});
}
}
public class ProductsController: Controller
{
[ViewModelMapper(typeof(ProductDetailsViewMapper))]
public ActionResult Details(EntityViewModel<Product> product)
{
return View(product.Instance);
}
}
IoC.Register(AllTypes.DerivedFrom(typeof(ViewModelMapper<>)));