Where should 'CreateMap' statements go? - asp.net-mvc

I frequently use AutoMapper to map Model (Domain) objects to ViewModel objects, which are then consumed by my Views, in a Model/View/View-Model pattern.
This involves many 'Mapper.CreateMap' statements, which all must be executed, but must only be executed once in the lifecycle of the application.
Technically, then, I should keep them all in a static method somewhere, which gets called from my Application_Start() method (this is an ASP.NET MVC application).
However, it seems wrong to group a lot of different mapping concerns together in one central location.
Especially when mapping code gets complex and involves formatting and other logic.
Is there a better way to organize the mapping code so that it's kept close to the ViewModel that it concerns?
(I came up with one idea - having a 'CreateMappings' method on each ViewModel, and in the BaseViewModel, calling this method on instantiation. However, since the method should only be called once in the application lifecycle, it needs some additional logic to cache a list of ViewModel types for which the CreateMappings method has been called, and then only call it when necessary, for ViewModels that aren't in that list.)

If you really don't want to use a bootstrapper, then at least a static constructor is an easy way of ensuring your CreateMap is called at most once. (With less messing around and more thread proof than Jonathon's answer.)
public class AccountController : Controller
{
static AccountController()
{
Mapper.CreateMap<Models.User, ViewModels.UserProfile>();
Mapper.CreateMap<Models.User, ViewModels.ChangePassword>();
}
}

If you use profiles, you can place all of your "CreateMap" calls there. Additionally, you can create a static bootstrapper class that contains your configuration, and have the startup piece just call the bootstrapper.

OK, the way I'm currently doing it is this:
I add some logic to the constructor of my BaseController, which runs the 'CreateMappings' method, but only once per Controller Type:
public abstract class BaseController : Controller
{
public BaseController()
{
if (!controllersWithMappingsCreated.Contains(GetType()))
{
CreateMappings();
controllersWithMappingsCreated.Enqueue(GetType());
}
}
protected virtual void CreateMappings() { }
}
In each concrete controller, I use CreateMappings to declare the mappings for all the Models/ViewModels relevant to that controller.
public class AccountController : BaseController
{
public AccountController() : base() { }
protected override void CreateMappings()
{
Mapper.CreateMap<Models.User, ViewModels.UserProfile>();
Mapper.CreateMap<Models.User, ViewModels.ChangePassword>();
}
}
I also found some interesting alternatives involving Attributes here and here, however they strike me as a bit overcomplicated.

Related

PlayFramework: The relation between Controller and Dependencies Injection

Now I am reading PlayFramework's official document which explains DI like this
There are two ways to make Play use dependency injected controllers.
I can't imagine how they are related, so what do they mean?
Why do we need putting the concept of DI into the Controller?
Could anyone explain?
In earlier versions of Play, controllers had static methods. This in turn lead to lots of either static code or singletons because static controllers couldn't easily share code or service objects. This also made testing harder than it had to be.
By moving to dependency injected controllers, everything can now be object-based (in place of the earlier class-based approach) and so shared instances or dedicated code can be passed into controllers.
Imagine a app that manages items of some type. Items are stored in a database, so some configuration is required.
public class StaticController extends Controller {
// active record approach
public static Result getItems() {
// static call to Item
List<Item> items = Item.findAll();
// do other stuff
}
}
When testing this, StaticController and Item are tightly coupled. Compare this to an approach using DI, in which a DAO can removed that coupling.
public class InjectedController extends Controller {
private final ItemDao itemDao;
public InjectedController(final ItemDao itemDao) {
this.itemDao = itemDao;
}
public Result getItems() {
// static call to Item
List<Item> items = itemDao.findAll();
// do other stuff
}
}
Because ItemDao can be an interface, coupling is massively reduced and testing just because a lot easier.

Adding users to roles outside of controller using MVC template

I'm using the standard MVC template and can happily create users and add them to roles from my controller.
My question is can I do this from one of my Models?
To clarify I'd like to move the new user logic from my controller to my UserSetting class
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(UserSettingsViewModel model)
{
if (ModelState.IsValid)
{
UserSetting userSetting = new UserSetting(model);
UserSetting.Create(userSetting);
}
}
My UserSetting Class:
public class UserSetting : Controller
{
private ApplicationUserManager _userManager;
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
public static void Create(UserSetting userSetting)
{
switch (userSetting.AccountType)
{
// InternalUser
case 0:
AddOrUpdateInternalUser(userSetting);
break;
// ExternallUser
case 1:
AddOrUpdateExternalUser(userSetting);
break;
// InternaDoctor
}
}
public async void AddOrUpdateInternalUser(UserSetting userSetting)
{
var db = new V2Context();
db.UserSettings.AddOrUpdate(userSetting);
await UserManager.RemoveFromRolesAsync(userSetting.UserName, UserManager.GetRoles(userSetting.UserName).ToString());
await UserManager.AddToRolesAsync(userSetting.UserName, "newrole");
db.SaveChanges();
}
}
Honestly, your code doesn't look too bad to me, at least in the sense of being concise. The controller is supposed to be responsible for things like working with the database, so I don't see a strong need for you to abstract any of that away. You might be able to turn like three lines of code into one by calling a method on a helper class, but does that really make any difference in the long run? No, and in fact, one could argue that you are actually adding complexity at that point, such that you now have to look in two places rather than one, just to move such a small amount of code out.
Also, if you were to move this code out to a helper class, then you would also need to inject your context into it. A lot of developers make the fatal mistake of trying to new up their context inside another class, and that will only cause problems.
Personally, I just try to keep my action methods light and create protected methods on the controller, which the actions utilize, to do the heavy lifting. It's the same practice Microsoft follows in their sample code for things like Identity. Long and short, keep the code in the controller unless there's an exceptionally good reason to move it out.
If your actions are getting too heavy, refactor the code out into private/protected methods (depending on whether you care about being able to subclass the controller or not) on the controller. Then, if you have code that is applicable to more than one controller, factor that out into some helper class that each can utilize.

Purpose of public NonAction methods in MVC

i have just started working in MVC and I have one doubt.
Instead of Nonaction method , we can create private method in controller or we can also write method in model and call that from controller.
So , what is the real purpose to use public NonAction method in MVC ?
(I restructured the answer to better address the questions in the comments)
I think, the attribute is here only for better flexibility. As a framework designer, one wants to relax coding constraints off the end user as much as possible. Requirement of not having public non-actions may sound good "in general" but may be too restrictive for some projects. Adding [NonAction] solves their problem (introduced by their bad design though) - and obviously you're not forced to use the attribute, so it's a win-win from a framework designer perspective.
Another reason may be legacy - in the earlier MVC versions only methods marked with [Action] where considered as actions. So when they relaxed the requirement (and all public methods became treated as actions) they kept [NonAction] so that developers won't get too confused.
In general, using NonAction is a bad practice - exactly for the reasons you stated. If something shouldn't be an action, it should not be public in the first place.
Problem with public non-action methods on the controller is that they make people tempted to instantiate your controller and call the method, instead of separating out the common logic:
Compare
public class MyController : IController
{
public ActionResult Foo(long orderId)
{
var order = new OrdersController().GetOrder(orderId); //GetOrder is public
...
}
}
with
public class MyController : IController
{
public ActionResult Foo(long orderId)
{
var order = _orderService.GetOrder(orderId);
...
}
}
The first approach leads to increased coupling between controllers and non-straightforward code in the actions. Code becomes difficult to follow and refactor, and cumbersome to mock/test.
Besides increased coupling, any public non-action method is a security hole - if you forget to mark it with [NonAction] (or, better, change away from public) - because it's treated as normal action and can be invoked externally. I know the original question kinda implies you surely would never forget to attach the attribute if needed, but it's also kinda important to understand what can happen if you would ;) Oh well, and as we're on this, it seems to me that "forgetting the attribute" is more theoretically probable, comparing to "forgetting to make the method private".
Sometimes people say having public non-actions is necessary for unit testing, but again, when something is not an action it most likely can be isolated in a separate class and tested separately. Moreover, even if it's not feasible for whatever reason, marking a method public for testing purposes only is a bad habit - using internal and InternalsVisibleTo is the recommended way.
This kind of situation may be caused by requirements some testing framework such as you need to do unit testing on that method then you to expose it although its a bad design but can't change these had to bear it out.
By default, the MVC framework treats all public methods of a controller class as action methods. If your controller class contains a public method and you do not want it to be an action method, you must mark that method with the NonActionAttributeattribute.
Real purpose to use public NonAction
To restrict access to non-action method to notify MVC framework that given controller method is not action.
When you try to run a method with NonAction attribute over URL you get the error 404 as response to request.
Ref: http://msdn.microsoft.com/en-us/library/dd410269%28v=vs.90%29.aspx
For Detail: http://weblogs.asp.net/gunnarpeipman/archive/2011/04/09/asp-net-mvc-using-nonactionattribute-to-restrict-access-to-public-methods-of-controller.aspx
This is beneficial when the Url are not case sensitive. So that for example if you have the request Home/About this goes to HomeController and About action, as well as hOmE/AbOUT is going to the same controller and same action method.
Like below
public class HomeController:Controller
{
....
public ViewResult About()
{
return View();
}
public ViewResult aBOut()
{
return View();
}
}
The framework can’t determine which about function to call, and throws the exception telling that the call is ambiguous.
Of course one way to fix this problem is to change the action name.
If for some reason you don’t want to change the action name, and one of these function is not an action, then you can decorate this non action method with NonAction attribute. Example:
[NonAction]
public ActionResult aBOut()
{
return View();
}
By default, the MVC framework treats all public methods of a controller class as action methods. If your controller class contains a public method and you do not want it to be an action method, you must mark that method with the NonActionAttribute attribute.
We are using controllers as binding drivers with custom ASP pipeline, each driver is responsible for rendering one section (partial view) of result page. Then we are using public methods like:
[NonAction]
publi int GetOrder()
to resolve sections order on page or other to resolve authorization for current user (e.g. if current section is editable or just read-only).
So you should not restrain yourself to think about Controller as only a way to handle requests but also as a tool to build your custom framework for rendering page. That way we keep our Controllers responsible for exactly one task and we are separating domain concerns.
ASP.NET is highly customizable. Assume you are going to change the default behavior of the framework by overriding the MVC HTTP handler. Maybe you want to customize the logging logic depending on the controller, which is used. Some controllers implement your ILoggingController interface with the method IControllerLogger GetLogger(). For this method you need to write a public non-action method.

Inject different repository depending on a querystring / derive controller and inject the repository depending on the controller type / ASP.NET MVC

I have a search form that can search in different provider.
I started out by having a base controller
public SearchController : Controller
{
protected readonly ISearchService _searchService
public SearchController(ISearchService searchService)
{
_searchService= searchService;
}
public ActionResult Search(...)
{
// Use searchService to query and return a view.
}
}
And child controllers
TwitterController : SearchController
{
...
}
NewsController : SearchController
{
...
}
I use StructureMap to insert all my dependencies in the controller. With this setup, I was able to change the SearchService depending on the type of the controller being instanciated.
x.For<ISearchService>().ConditionallyUse(o =>
{
o.TheDefault.Is.OfConcreteType<NewsSearchService>();
o.If(c => c.ParentType == typeof(TwitterController))
.ThenIt.Is.OfConcreteType<TwitterSearchService>();
...
});
That even allowed me to set different Views for each controller, (just putting the corresponding folder (Twitter, News...) and the Parent controller is still handling all the Search, with a simple
return View(results)
which is displaying the correct view specific to twitter, news, or other
Now that was cool and looked great, I a single form and the different views are displayed in tabs on the same page. That's where it starts to get complicated with this approach. The form has to post to /Twitter to search in twitter, to /News to search in news... which means I should change the action parameter of the form depending on which tab I am and display the correct tab on when the form returns depending on.. the url? craziness follows.
If you have built something like this already or know what's the best approach to this, please advices are welcome.
Now I think I would have less pain using a parameter in the form and posting to a single controller. I am thinking of injecting the correct SearchService depending on this parameter. What would be the best approach? I thought of using a model binder,
So I would have my ActionMethod that look like this:
public ActionResult Search(ISearchService service, Query query)
{
var results = service.Find(query);
}
But I think would need to make a call like this in the ModelBinder
ObjectFactory.GetInstance(...);
Based on the querystring parameter that describe which provider to use, and that doesn't seem more elegant to me. I feel stuck, help :(.
Whenever you need to vary a dependency based on a run-time value, Abstract Factory is the general solution.
Instead of injecting ISearchService into your Controllers, inject an ISearchServiceFactory:
public SearchController : Controller
{
private readonly ISearchServiceFactory searchServiceFactory;
public SearchController(ISearchServiceFactory searchServiceFactory)
{
if (searchServiceFactory == null)
{
throw new ArgumentNullException("searchServiceFactory");
}
this.searchServiceFactory = searchServiceFactory;
}
public ActionResult Search(...)
{
// Use searchServiceFactory to create an ISearchService based on
// run-time values, and use it to query and return a view.
}
}
It is not entirely clear to me which run-time value you need to vary on, but assuming that it's the Query, ISearchServiceFactory might be defined like this:
public interface ISearchServiceFactory
{
ISearchService Create(Query query);
}
I was trying to figure out how to use the abstract factory pattern and still let structuremap resolve all the dependencies of my components.
I believe that is the way I am going to implement it, but I submit this here to get some feedback if someone would read this.
As explain in the previous answer, I do not want to build the whole object graph depending on which provider I need in the Abstract factory.
ie :
class StatServiceFactory : IStatServiceFactory
{
public IStatService Create(string provider)
{
switch(provider)
{
case "blog":
return new StatService(IFacetRepository,ISearchManager,IConfigManager,BooleanQueryBuilder);
//How to resolve the Config, the SearchManager, and BooleanQueryBuilder?
//Add more abstract factories? It starts to get messy in my opinion...
}
}
}
What I can do is have the abstract factory use my container to create an instance of my search managers depending on a parameter (coming from the querystring in my case)
Structuremap allows to create named instances this way :
x.For<ISearchManager>().Use<AbcSearchManager>().Named("Abc");
x.For<ISearchManager>().Use<DefSearchManager>().Named("Def");
I need a way to inject the container in my Abstract factory.
I would probably wrap the container in a wrapper defined like this. That would keep me from leaking Structuremap into my project. I dont need more that those 2 features within the abstract factory anyway, but it is not necessary:
public interface IContainerWrapper
{
object GetInstance<T>();
object GetNamedInstance<T>(string key);
}
and the implementation :
public class ContainerImpl : IContainerWrapper
{
private readonly Container _container
public ContainerImpl(Container container)
{
_container = container;
}
...
}
And setup StructureMap to resolve dependencies to my abstract factory like that :
x.For<IContainer>.Use(new ContainerImpl(this));
x.For<IFactory>.Use<Factory>()
My factory would be then much simpler and would create my instance like that :
public class SearchmanagerFactory
{
private readonly IContainerWrapper _container;
public SearchmanagerFactory(IContainerProvider containerProvider)
{
_container = containerProvider;
}
public ISearchManager Create(string provider)
{
//eed to handle the bad input for provider.
return (ISearchManager)
_container.Resolve<ISearchManager>(provider);
}
}
That seems pretty clean this way :).
Thoughts?
This is more an extensive comment than an answer to explain why an AbstractFactory seems complicated. Here is something that looks closer from the reality:
class StatServiceFactory : IStatServiceFactory
{
public IStatService Create(string provider)
{
switch(provider)
{
case "blog":
return new StatService(IFacetRepository,ISearchManager,IConfigManager,BooleanQueryBuilder);
//How to resolve the Config, the SearchManager, and BooleanQueryBuilder?
//Add more abstract factories? It starts to get messy in my opinion...
}
}
}
The FacetRepository is the same for any provider, but the SearchManager changes, the ConfigManager changes, and the BooleanQueryBuilder is an abstract class with different implementation for different provider (because every API doesnt use the same keyword for their queries) All those dependencies are currently resolved by structuremap, based on the type of the controller.
I would really like to keep the benefit of StructureMap here, rather than using factories all the way, for each different pieces.'
Please see my edit at the end of my question for another suggestion to my problem.

How are you able to Unit Test your controllers without an IoC container?

I'm starting to get into Unit Testing, Dependancy Injection and all that jazz while constructing my latest ASP.NET MVC project.
I'm to the point now where I would like to Unit Test my Controllers and I'm having difficulty figuring out how to appropriately do this without an IoC container.
Take for example a simple controller:
public class QuestionsController : ControllerBase
{
private IQuestionsRepository _repository = new SqlQuestionsRepository();
// ... Continue with various controller actions
}
This class is not very unit testable because of its direct instantiation of SqlQuestionsRepository. So, lets go down the Dependancy Injection route and do:
public class QuestionsController : ControllerBase
{
private IQuestionsRepository _repository;
public QuestionsController(IQuestionsRepository repository)
{
_repository = repository;
}
}
This seems better. I can now easily write unit tests with a mock IQuestionsRepository. However, what is going to instantiate the controller now? Somewhere further up the call chain SqlQuestionRepository is going to have to be instantiated. It seems as through I've simply shifted the problem elsewhere, not gotten rid of it.
Now, I know this is a good example of where an IoC container can help you by wiring up the Controllers dependancies for me while at the same time keeping my controller easily unit testable.
My question is, how is one suppose to do unit testing on things of this nature without an IoC container?
Note: I'm not opposed to IoC containers, and I'll likely go down that road soon. However, I'm curious what the alternative is for people who don't use them.
Isn't it possible to keep the direct instantiation of the field and also provide the setter? In this case you'd only be calling the setter during unit testing. Something like this:
public class QuestionsController : ControllerBase
{
private IQuestionsRepository _repository = new SqlQuestionsRepository();
// Really only called during unit testing...
public QuestionsController(IQuestionsRepository repository)
{
_repository = repository;
}
}
I'm not too familiar with .NET but as a side note in Java this is a common way to refactor existing code to improve the testability. I.E., if you have classes that are already in use and need to modify them so as to improve code coverage without breaking existing functionality.
Our team has done this before, and usually we set the visibility of the setter to package-private and keep the package of the test class the same so that it can call the setter.
You could have a default constructor with your controller that will have some sort of default behavior.
Something like...
public QuestionsController()
: this(new QuestionsRepository())
{
}
That way by default when the controller factory is creating a new instance of the controller it will use the default constructor's behavior. Then in your unit tests you could use a mocking framework to pass in a mock into the other constructor.
One options is to use fakes.
public class FakeQuestionsRepository : IQuestionsRepository {
public FakeQuestionsRepository() { } //simple constructor
//implement the interface, without going to the database
}
[TestFixture] public class QuestionsControllerTest {
[Test] public void should_be_able_to_instantiate_the_controller() {
//setup the scenario
var repository = new FakeQuestionsRepository();
var controller = new QuestionsController(repository);
//assert some things on the controller
}
}
Another options is to use mocks and a mocking framework, which can auto-generate these mocks on the fly.
[TestFixture] public class QuestionsControllerTest {
[Test] public void should_be_able_to_instantiate_the_controller() {
//setup the scenario
var repositoryMock = new Moq.Mock<IQuestionsRepository>();
repositoryMock
.SetupGet(o => o.FirstQuestion)
.Returns(new Question { X = 10 });
//repositoryMock.Object is of type IQuestionsRepository:
var controller = new QuestionsController(repositoryMock.Object);
//assert some things on the controller
}
}
Regarding where all the objects get constructed. In a unit test, you only set up a minimal set of objects: a real object which is under test, and some faked or mocked dependencies which the real object under test requires. For example, the real object under test is an instance of QuestionsController - it has a dependency on IQuestionsRepository, so we give it either a fake IQuestionsRepository like in the first example or a mock IQuestionsRepository like in the second example.
In the real system, however, you set up the whole of the container at the very top level of the software. In a Web application, for example, you set up the container, wiring up all of the interfaces and the implementing classes, in GlobalApplication.Application_Start.
I'm expanding on Peter's answer a bit.
In applications with a lot of entity types, it is not uncommon for a controller to require references to multiple repositories, services, whatever. I find it tedious to manually pass all those dependencies in my test code (especially since a given test may only involve one or two of them). In those scenarios, I prefer setter-injection style IOC over constructor injection. The pattern I use it this:
public class QuestionsController : ControllerBase
{
private IQuestionsRepository Repository
{
get { return _repo ?? (_repo = IoC.GetInstance<IQuestionsRepository>()); }
set { _repo = value; }
}
private IQuestionsRepository _repo;
// Don't need anything fancy in the ctor
public QuestionsController()
{
}
}
Replace IoC.GetInstance<> with whatever syntax your particular IOC framework uses.
In production use nothing will invoke the property setter, so the first time the getter is called the controller will call out to your IOC framework, get an instance, and store it.
In test, you just need to call the setter prior to invoking any controller methods:
var controller = new QuestionsController {
Repository = MakeANewMockHoweverYouNormallyDo(...);
}
The benefits of this approach, IMHO:
Still takes advantage of IOC in production.
Easier to manually construct your controllers during testing. You only need to initialize the dependencies your test will actually use.
Possible to create test-specific IOC configurations, if you don't want to manually configure common dependencies.

Resources