简体   繁体   中英

ASP.NET MVC3 generic controler

I have written a bit of code today which smells somewhat.

public class SomeController : GenericController<SomeViewModel, SomeModel>

Here is a Generic Controller constrained to a particular Model and ViewModel; now what smells is the fact that I am defining the relationship between the Model and the ViewModel I don't mind that the Controller knows about the ViewModel that's fine. What I wish this to do is have the Controller ask the View Model somehow because that's where the coupling should be in my view. The only way I can think of is in the controller factory. That could inspect the supplied ViewModel and create and instance of the Controller with the Model defined at runtime.

so the above would just become

public class SomeController : GenericController<SomeViewModel, TModel> where TModel : Model

And only be typed at runtime. any ideas on how to do this? reflection? generics? attributes? or is this just a really bad idea?

============Edit===========

the reason for the use of generics is there is a lot of shared code throughout the controllers the controllers use services which intern use repositories. the services and repositories depend on the type of domain object. the methods such as public ViewResultBase Add(TViewModel viewModel) in the Generic Controller uses a generic mapper which converts the ViewModel to a Model and passes this to the service -> repository.

============Edit===========

heres a snippet from the base class showing some shared code utilising the generic arguments

    [HttpGet]
    public virtual PartialViewResult List(int id)
    {

        var model = BuildListDetails(id);

        return PartialView(model);
    }

    [Dependency]
    public IService<TDomainObject> Service { get; set; }

    protected IEnumerable<TViewModel> BuildListDetails(int id)
    {

        var nodes = Service.GetData(UserState.Current.User.UserID, id);
        if (nodes == null) return null;

        return nodes.Select(n => ModelMapperFactory<TDomainObject, TViewModel>.Instance.Create(n)).AsEnumerable();
    }

cheers,

Darin is right (as always). Controllers can work with different models and different views and different view models. Typing your controller to one specific view model and model is just pointless, unless you know for a fact that you will always use just that one view model and just that one model.

There is an association between view models and models. This association is handled in the controller. That's one of its purposes. Don't spend a lot of effort trying to genericize controllers, they typically only contain very specifc code related to its use, and have few options for reuse. When you do need more options, consider using aspects or base clases that just abstract the reusable part (some people authentication logic in a base class, which I don't agree with.. but it's a choice.. other people add their own custom IPrincipal, or other kinds of common features. In most cases, this would not require using generics).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM