Pregunta

I am fairly new to MVC5 Development and I have been doing a lot of reading about Layered Design, DI, IoC, etc... I feel that I am getting a grasp of concepts, however when it comes down to writing a good example I struggle. To ask my question I need to set a base and here is that base, the goal is to create a new Team:

public class Team
{
    public Guid Id { get; set; }
    public string OwnerId { get; set; }
    public string TeamName { get; set; }
    public virtual ApplicationUser Owner { get; set; }
}

public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        return await manager.CreateIdentityAsync(this, 
            DefaultAuthenticationTypes.ApplicationCookie);
    }
}

public class TeamMember
{
    public Guid Id { get; set; }
    public Guid TeamId { get; set; }
    public string ApplicationUserId { get; set; }
    public virtual Team Team { get; set; }
    public virtual ApplicationUser ApplicationUser { get; set; }
}

So the above is basically the models of how my database will look. I understand it is missing auto generated id remarks and few other things but lets just assume it will work.

Now proper MVC5 Layered Design dictates the following (Please correct me if I am wrong)

Controller:

  1. Controller will create a "Manager".
  2. Controller will call a Method in the Manager which will return a ViewModel.
  3. Controller will pass this ViewModel to the View.

Manager:

  1. Manager will validate and ensure user has the permission to create a new team
  2. Manager will create an empty instance of the ViewModel
  3. Manager will call services to populate the Data in the ViewModel

Service:

  1. Service will use business logic to determine which Method in the Data Layer to call.
  2. Service will take the output of the method in Data (Typically Dto) and pass it back to the calling Manager.

Data:

  1. Execute a query and return back IEnumeration of Dtos (if applicable) back to the calling Service.
  2. Execute a query that will insert data into a table and return back that result.

Assuming that what I have written above is correct, I then would have the following code to create a new Team:

Controller:

public class TeamController : Controller
{
    public ActionResult Create(string teamName)
    {
        var TeamManager = new TeamManager();
        var result = TeamManager.CreateTeam(teamName);
        if (result == true) return View("TeamCreated");
        return View("TeamNotCreated");
    }
}

Manager:

public class TeamManager
{
    ApplicationUser User = ???

    public bool CreateTeam(string teamName)
    {
        var service = new TeamService();
        var team = service.CreateTeam(teamName, User.Id);
        service.CreateTeamMember(team.Id, User.Id);
        return true;
    }
}

Service:

public class TeamService
{
    public Team CreateTeam(string teamName, string userId)
    {
        //Call Data query
    }

    public void CreateTeamMember(Guid teamId, string userId)
    {
        //Call Data query
    }
}

I believe that the examples above model the Layered design I have described before. As such I have a few questions that I am trying to figure out but I've had no luck, so any help on this is most appreciated!

  1. How should I be instantiating the TeamManager? Should this be done via injection and passed in to the controller? Should I create a new instance of that object every time any action on the Team controller is called or should I using Ninject singleton option and cache the creation of that object for first time and then reuse it?
  2. How do I get the ApplicationUser inside TeamManager?
  3. How do I actually get the DbContext? I understand I can create a new instance and just call whatever the method, but what is the correct way? Does it need to be cached passed in to data all the way through the TeamManager? Does it needs to be created every time, if so where?

I was unable to find any simple examples online, anything I've found over complicates and confuses me even more.

¿Fue útil?

Solución

There is no MVC5 Layered Design definition, it's up to you to come up with design make sense to you. There is no need to have Manager layer for simple data fetching operations.

  1. How should I be instantiating the TeamManager? Should this be done via injection and passed in to the controller? Should I create a new instance of that object every time any action on the Team controller is called or should I using Ninject singleton option and cache the creation of that object for first time and then reuse it?

You have to use dependency injection. There are a lot of containers such as Autofac, Ninject in order to do it.

How do I get the ApplicationUser inside TeamManager?

You could use dependency injection to inject the application user.

How do I actually get the DbContext? I understand I can create a new instance and just call whatever the method, but what is the correct way? Does it need to be cached passed in to data all the way through the TeamManager? Does it needs to be created every time, if so where?

Wrap DBContext in an interface and use DI container to inject it to where necessary.

This is one of the samples I have done for MVC5, you can have a look how DI is used.

Otros consejos

Let's look at some definitions from the Microsoft centric point of view for MVC.

Model

This is where you build your data objects. The source could be a database, another web site, some data feed, etc. This is the layer where you communicate with your storage mechanism. The Model may perform validation of the data before it is stored.

View

This is where you build your presentation objects, the UI. These objects will be transformed into HTML before being sent to your users. This is how your user interacts with your application. When your user clicks on a button, it View makes a call to the Controller to process the action.

Controller

This is where you build your glue of your application. A simple controller may do nothing more than tell the View to move something around on the page. A more complicated Controller could perform authentication, authorization, pass data along to a Model for storage (or get data from one), or any number of additional tasks. This is also where your application will respond to most actions that user performs in the View.

For more details about the conceptual interaction between the layers, take a look at Model-View-Controller: Does the user interact with the View or with the Controller?

Licenciado bajo: CC-BY-SA con atribución
scroll top