Model In MVC Mo Rezai
Aims and Objectives To examine To examine MVC processing cycle again To explore the overall application architecture To study the architecture of Model To explore the use of Repository pattern for data access
Application Architectures Applications are divided into a number of tiers No of tiers is dependent on application requirements This is known as n-tier architecture Tiers often are; Presentation Responsible for display Responsible for navigation Business/Service tier Provides business logic for application Can service different client types Integration/Data tier Provides storage and retrieval of data from external sources Integrate with 3rd party systems Question: What are the advantages of n-tier? Answer: Clean separation of functionality, easier management of development, etc
MVC Processing cycle CustomerDetails.aspx (View) URL for Customers CustomersController (Controller) Customers.aspx (View) Customer (Model) SQL
MVC Application Architectures .. Request View Data Storage Controller Business Tier Presentation Model Integration Access Client tier: Across the network we could have many different types of clients some of which could be hand-held devices, desktop applications or application in their own right that require access to our functionality or our back-end data. Client tier is responsible for painting the display, actually rendering the data within the client. Browser is in this tier. Presentation tier: Is code that is responsible for certain client types. They are there for thin clients. It is also code that controls the flow of interaction with the application. It could also be about control of access to the application. Business tier: Sometimes referred to as Service-tier. These are business objects that actually do the business logic. Business logic though is not about data access. Within this layer you will not have code that creates connection to database and fetch data from database, etc. Integration tier: Working with data such as creating connection to database and fetching data from data sources and writing to the sources, etc is done with code that ends up in the integration layer. This is sometime referred to Data Access Layer and provides us with object views of our database objects. For example if we have a table in the database, we can create a class representation of that table within this layer of our application. We like that because we could then write code in our service layer that would interact with the integration tier objects just as if these are regular objects. Within the service layer we see no references to database specific stuff. Resources Tier: These are persisitant resources such as file system, legacy, databases, etc.
What’s Model made of? Represents application data Represents application business rules MVC provides no model classes Application model can be implemented using a variety of technologies. Examples; LINQ to SQL, Entity Framework, nHibernate, WCF, ASMX, Plain Objects Controller should be totally independent of model-implementation technology They should be loosely coupled Essentially model represents two things; One is application data. Purely stuff that we have in our persistent repositories such as databases, filestores, legacy, etc. If you have a database you need to CRUD, we, you need to write code. Imagine you write a class that communicates with a database and executes sql commands against the database – you have written code like that before. Here if you were to encapsulate that code in a class, that class would be a model. In those classes there will be no business logic executed. Purely access to data and that is it. You could then pass this data to another component that does the business logic on that data – it does something interesting for us. That class would then be yet another Model. MVC is purely about the controller and the view. Nothing in it for the model. You can build your model using quite a lot of technologies. Could be Web Services like ASMXs, could be WCF Web Services, LINQ to SQL, etc. Should have low coupling between controller classes and model classes. This makes the system more amenable to change downstream.
Model Architecture Model is often broken up into separate layers We will use Integration Tier Persisting and retrieving data Business/Service Tier Performs computation, provides Services to Presentation Tier Business Tier Model Integration Data Access As we said earlier, model is divided into two different categories. Essentially model is divided into Integration tier and the Business or Service tier. Integration tier is the bit that just does the talking to data sources and no business logic. This is where we use technologies such as LINQ and Entity Framework to communicate with databases. Integration tier exposes functionality to clients via Interfaces. Clients are mosly the objects in the business/Service layer. Business or service tier are code heavy. This is where we write our classes in vb, c#, fortran.net, cobol.net. These classes often use the integration tier in a loosely coupled manner. It uses them through using their Interfaces. Business tier though also exposes functionality to clients using Interfaces.
Integration Tier Performs Object to Relational Mapping (ORM) Persist and retrieve object state in a relational DB The idea is that we do not like to see database related code in our code. We do not want to see objects of the connection, command and sql in our code. We would like to write code and in our code we would like to be using database objects just like any other object. For example we would like to see a table product in the database as product class in our environment. This class may not have useful methods but it would have useful properties such as product_id and product_name and product_price, etc. With ORM - Essentially what it is, is that we create classes of our database entities and we bring those classes into our development environment. We can then within our code to create objects of the classes and basically work with the objects. LINQ to SQL is an alternative to SQL. It is a programming language with its own syntax and constructs that we basically use to work with the ORM objects. Essentially we bring the objects to our environment as ORMs. Within our application domain we communicate with the object using LINQ to SQL. Remember – Thare just layers of abstraction. There was a reason we did ADO.Net. The reason is that all this is simply built on ADO.Net classes. We are getting away from code because we think it is going to make us more productive, that is all. LINQ to SQL or Entity Framework facilitate for managing and accessing relational data as objects Objects are entity objects Represent entities in application domain
Integration Tier ... Working with Entity Framework Create entity classes that map to database tables Create DataContext object Write LINQ queries to work with data through using DataContext object So a few things we have to do to work with data; We create a presentation of the database table to tables in our application environment essentially as objects. We then would have access to this thing we call the DataContext object and this basically works as the connection to the data objects. We write LINQ queries to talk to the data using the DataContext object
Integration Tier ... Entity classes map to database tables. Two ways to write them; By hand Classes are marked up with attributes to define DB mapping Table attribute defines which table, Colum attribute defines which column, etc. Use VS Object Relational Designer Drag and drop Generates class and property names Names and properties default to those in table All seem quite complicated but it really does not have to be. Two ways to do this; The complicated way – that is you write the classes and mark them up with various attributes that make them ORM classes. Use Visual Studio Object Relational Designer – Drag and Drop tables from the database and it basically generates the classes for you and in doing so it uses various properties of the tables to create class name and properties. You can change these if you want. The name of the table in the database in this case must have been video_categories. It has created the object and called it video_category. Note the singular for the name. Properties map to columns in the table like for like. More on this in the tutorial.
Integration Tier ... ORM designer creates DataContext class DataContext has a property mapped for each class mapped to a table Inherits System.Data.Linq.DataContext For example Product class is represented by Products property Property is a data source for accessing objects using LINQ This thing called the DataContext is kind of important and in the tutorial we see how it works. Suffice to say that this class is the connector between our code and the entity classes. This class has properties that map to properties of the entity classes and by inference to the tables in the database. For example if we have a table in our database called Product. We create the entity class from the table and the name of the class by default becomes Product. This would also create a DataContext class called ....... If one column in the DB table is Name. One property of Product Class would be Name.
Integration Tier ... LINQ allows queries to be expressed in OO manner Use class and property names Not like SQL that uses tables, columns General form; From range_variable In data_source Select variable In VB; Private _context As New ProductDBEntities() From p In _context.Products _ Where p.Price>10.00 _ Orderby p.Name _ Select p Private _context As New ProductDBEntities() From p In _context.Products _ Where p.Price>10.00 _ Orderby p.Name _ Select p We first create an object of datacontext, in this case to the ProductDBEntities called _context. ProductDBEntities provides the connection between our application and the Entity Framework Object. You can think of it as the connection string that you have already seen but it obviously is quite different. p here is just an alias that we use and the LINQ expression in VB seem quite SQL like though it might have been shuffled somewhat where you get the select at the end instead of beginning and the rest of it.
Integration Tier ... LINQ provides a solution for implementing the integration tier We need a structure for the implementation Data Access Object (DAO) pattern provides the structure Separates logical and physical views of data Hides schema and implementation- SQL Server, etc Also referred to as the Repository pattern Loose coupling between DAO and clients is desired. We achieve this by defining DAO Interfaces Essentially we have a few things that provide the solution for implementing Integration tier. LINQ provides us with the methods for cruding the data. But LINQ expressions are embedded in classes. So we need to implement classes and it does make sense to have a structure for the implementation to follow. There is this pattern called the DAO pattern which is also referred to as the repository pattern. The idea is to separate the database implementation heavy code of things from what we really want to do. We always look for developing components that are loosely coupled. Here we are creating DAO classes that will be used by client code in service layer to get access to data. We really want as little dependence as possible between the two set of classes. It makes sense because we would like to be changing any of the classes without worrying about how they affect the others.
Integration Tier ... DAO Interface Implementation Public Interface IProductDAO Function GetProducts() As IList(of Product) Function GetProductCategories() As ... End Interface DAO Implementation Public Class ProductDAO Implements IProductDAO Private _context As New ProductDBEntities() Public Function GetProducts() As IList(of Product) _ Implements IProductDAO.GetProducts() Dim Products = From p In _context.Products _ Orderby p.Name Select p Return Products.ToList() End Function ........... End Class This is how we usually achieve loose coupling. We create interfaces and we implement to an interface. You have to think about the client of this application. Client would in this case create pointers to objects of the Interface albeit the actual object has to be of the implemented type. Later on if you change your implementation here, this would impact a bit less on the client. Here we are demonstrating an implementation of repository pattern through using an interface class (could have used an abstract class). The point about this is that here we are implementing using a database as the back end. We could have implemented using an in-memory database. The point is that the service layer will be using the data access layer oblivious to exactly how it is implemented.
Service Tier Clients to the classes in Service Tier are the controllers Rule: MVC Application must always have a Service Tier Even if it is just a wrapper around DAO layer Later we might want to build Web Service of a Service A Service might use more than one DAO Service classes must also define Interfaces Services are not just about Data Access – There could be business logic Service tier’s clients are the controllers. We must always have service tier even if it is just a wrapper for the integration tier. This is because we might need to add facilities later. For example we might later decide to expose a Service as Web Service. We may for example build a Service that uses a number of DAOs, for example data may come from a number of databases. Service classes should follow the same implementation structure as the DAOs in integration tier. They should define Interfaces and take up practices that promote loosely couple application development. Services could then change later with less of an adverse affect on their clients. Of course services are not just about data access. You could have quite complex business logic within the services too. In fact all the business logic that there is to be has to be in the service layer.
Service Tier ... Service Interface Implementation Public Interface IProductService Function GetProducts() As IList(of Product) Function GetProductCategories() As ... End Interface Service Implementation Public Class ProductService Implements IProductService Private _productDAO As IProductDAO _productDAO = New ProductDAO Public Function GetProducts() As IList(of Product) _ Implements IProductService.GetProducts() Return _ProductDAO.GetProducts() End Function ........... End Class Interface looks just like the one we have seen before. Note that in the implementation we have a pointer to the IProductDAO Interface (and not to ProductDAO, the concrete implementation) called _productDAO.
To sum up … In this lecture; We have explored the overall architecture of the application We have talked about the Model in MVC We have seen implementation of the Model
References Gamma et al, "Design Patterns - Elements of Reusable Object-Oriented Software", Addison-Wesley. Walther, S, "ASP.NET MVC Framework", SAMS