Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Using Teamwork.com, your team will know what they have to do, when it must be done and who
needs to do it. They'll know exactly where to look to find and store everything they need. And so
will your clients. Whether it's the head office or your latest lead, your clients can keep up-to-date
with what's going on without having to bug you -- something you'll both feel better about. And
information is not just stuck in your computer either : using our beautiful Android, iPhone and
iPad apps, your team can do their work where they need to be; it doesn't matter if that's in a
workshop, a meeting room or sitting at their desk. Once you try Teamwork.com, you won't know
how you ever managed without it.
View our features
These are the below Database tables for the Task Management
System:
Projects
S.No
1
2
Column Name
ID
ManagerID
Data Type
Number(9)
Number(9)
Description
Name
Varchar(50)
Description
Varchar (50)
EstStartDate
Date
EstCompletionDate
Date
Users
S.No
Column Name
Data Type
UserID
Number(9)
Name
Varchar(50)
Username
Varchar(50)
Userpassword
Varchar (50)
Varchar(50)
RoleID
Number(9)
Status
Number(9)
Description
User Contacts
S.No
1
Column Name
ID
Data Type
Number(9)
UserId
Number(9)
ContactID
Number(9)
Description
The purpose of this article is to create a simple Task Management System(TMS) that
will help the user to create a task, edit the task and to view the same by using MEF
4.0, WCF , Entity Framework 4.0 with some architectural patterns etc.
Introduction
A Task Management System(TMS) allows managers to track the progress of a task assigned to
team member(s).This helps the manager to keep track of the work progress. This is useful
especially when he has to keep track of many tasks assigned to a large number of his staff.
Purpose
The purpose of this article is to create a simple Task Management System(TMS) that will help
the user to create a task, edit the task and to view the same by using MEF 4.0, WCF , Entity
Framework 4.0 with some architectural patterns etc.
Technologies In Use
1. Dot Net Framework 4.0
2. MEF 4.0
3. WCF 4.0
4. Entity Framework 4.0
5. Asp.net 4.0
6. Java Script
7. Sql Server 2008
8. Design Patterns
1. Adapter Pattern
The tables tblPriority,tblStatus are lookup tables whose values are as under respectively
The user table(tblUser) contains the information about the current users/team members of the
system.In our current TMS, there are 4 users being listed in the table.
The tblTaskActivity table contains the data about the current task being assigned to the user,the
status etc.
We also have 5 stored procedures viz
1. usp_GetPriority (Gets the record from the Priority table)
2. usp_GetStatus (Gets the record from the Status table)
3. usp_GetUser (Gets the record from the User table)
4. usp_GetTaskList (Gets the tasklist for the users)
5. usp_InsertTask (Inserts a new task in the Task Activity table)
6. usp_UpdateTask (Updates an already existing task in the Task Activity table)
Project Structure
It's a simple three tire model with which we are familiar with.
TMSDataService is the data service layer.The MEF will come here which will interact with the
EF for accessing the dB operation.Once done, the result will be returned to the TMSService
TMSService is the service layer where WCF will reside.It will accept the data from the
TMSDataService layer and will transform the record set to the custom entities via Adapter
pattern.Once done , it will return the data back to the TMSView.
TMSView is the view of the TMS system. It will get the record from the TMS Service layer and
will display those. The entire system interaction is a two way phenomenon.Since for every client
only proxy instance creation is sufficient, henceforth, we can use a singleton pattern in the view
layer that will interact with the service layer.
The DataAccessStrategy folder will have the logic for composition of the data and will interact
with the EF through the TMSModel.cs class which is a concrete class.The
TMSCompositionHelper.cs file is the one that will create the composable parts and will invoke
the needed component at runtime depending on the request made by the client.
N.B.~A detailed description of MEF is beyond the scope of this article.For learning how it work,
you can refer to my other article on MEF
Now we will create the entity model.For doing so let us follow the below steps
Step 1:Right click on the Components folder->New Item->Ado.Net Entity Data Model. Give the
name as "TMSSqlDataModel.edmx"
So from the Model Browser we can figure out the tables and the store procedures being choosen
from our DB model. At this juncture it will be worth mentioning that, the conceptual EF model
treats the store procedures as functions and the tables as entities.
At present we will see how we can import functions to map to Stored Procedures.We will
basically use three store procedures for our demonstration purpose
viz.usp_GetPriority,usp_GetTaskList,usp_InsertTask,usp_UpdateTask.The other two SP's viz
usp_GetStatus,usp_GetUser will follow the pattern as how we will do for usp_GetPriority
Using Import Functions to Map Stored Procedures usp_GetPriority
The usp_GetPriority will return entity of type tblPriority.This procedure selects entire rows from
the tblPriority table.Because of this one-to-one mapping, we can create a function import from
this stored procedure that returns an tblPriority type.
For that to happen, we need to follow the below steps
Step 1:Right click on the usp_GetPriority and select Add Function Import from the menu.
The Add Function Import wizard will appear as shown in the below figure
Step 2:Give a proper "Function Import Name" say GetPriority and select Entities under
"Returns a Collection Of" where we need to choose the entity "tblPriority"
And then click on the "OK" button.We can figure out that under the "Function Imports" folder,
the GetPriority function is listed.
So, let us follow the similar step for the other two SP's viz usp_GetStatus,usp_GetUser
Using Import Functions to Map Stored Procedures usp_GetTaskList - Usage of
ComplexType
This store procedure needs some special attention.Let us first see the script
SELECT
From
Join
Join
Join
t.TaskId
,t.TaskName
,p.PriorityID
,p.PriorityName
,s.StatusID
,s.StatusName
,u.UserID
,u.UserName
,t.TaskCreatedOn
,t.EstimatedTime
,t.ActualTime
tblTaskActivity t
tblPriority p ON t.Priority = p.PriorityID
tblStatus s ON t.Status = s.StatusID
tblUser u ON t.AssignedTo =u.UserID
We can make out that, this store procedure is accessing three tables viz
tblTaskActivity,tblPriority,tblStatus,tblUser for getting teh result set. So we cannot find a single
entity as it's corresponding mapping model in the EF framework.
However,the Entity Data Model supports ComplexType. A ComplexType is like an entity
without an EntityKey and therefore cannot be change-tracked or updated.
Step 1:From the Model Browser, start the Function Import Wizard for the usp_GetTaskList
function.Change the Function Import Name to GetTaskList.
Step 2:Let us click on the Get Column Information button. This will cause the designer to
execute the stored procedure so that it can read the schema of the result set. The schema will be
displayed in the grid below the button.
Step 3:Let us click on the Create New Complex Type button below the grid.Rename the new
complex type in the text box to TaskList.
Step 4:Lastly,click the OK button.
In addition to the new function, we can find the new Complex Type in the Model Browser as
shown in the below figure
One of the great advantages of returning a Complex Type rather than an Anonymous Type from a
LINQ projection,is that we now have a strongly-typed class to work with.
Mapping Insert Stored Procedures usp_InsertTask to Entities
Let us follow the below steps inorder to accomplish the same
Step 1:In the designer, right click on the "tblTaskActivity" entity and select Stored Procedure
mapping.
Step 1:Click <Select Insert Function> and then click the drop down arrow that appears.This
exposes the list of all Functions found in the Store metadata.
Step 2:Select usp_InsertTask from the list. The designer will do its best job of matching the
stored procedures parameters with the entity properties using the names.If it does not, then we
have to do so by ourself
The benefit of mapping the stored procedure parameters to the entity properties is that we donot
have to write code to give the correct pieces of data to the stored procedure rather the Ef will use
these mappings to do that task.Type NewTaskId property into the Result Column Bindings and
hook it up to the TaskID property.The stored procedure returns the new ID for the inserted row.
This mapping ensures that the new id is pushed back into the entity.
ObjectResult GetPriority();
ObjectResult GetStatus();
ObjectResult GetUser();
ObjectResult GetTaskList();
int SaveTask(tblTaskActivity task);
The concrete class "TMSModel" that implements the above interface is as under
using System.ComponentModel.Composition;
using System.Data.Objects;
using TMSDataService.DataAccessStrategy.Contract;
namespace TMSDataService.DataAccessStrategy.Components
{
[Export(typeof(IDataAccess))]
[ExportMetadata("TMSModelSQLMetaData", "SQLSERVER")]
public class TMSModel : IDataAccess
{
public ObjectResult GetPriority()
{
//Access the entity model from here
var tmsEntities = new TMSEntities();
return tmsEntities.GetPriority();
}
public ObjectResult GetStatus()
{
//Access the entity model from here
var tmsEntities = new TMSEntities();
return tmsEntities.GetStatus();
}
public ObjectResult GetUser()
{
//Access the entity model from here
var tmsEntities = new TMSEntities();
return tmsEntities.GetUser();
}
public ObjectResult GetTaskList()
{
//Access the entity model from here
var tmsEntities = new TMSEntities();
return tmsEntities.GetTaskList();
}
public int SaveTask(tblTaskActivity task)
{
var tmsEntities = new TMSEntities();
tmsEntities.AddTotblTaskActivities(task);
return tmsEntities.SaveChanges();
The export components are being assembled in the AssembleDataComponents() method and are
stored in the DataPlugins property.The [ImportMany] attribute helps to store more export
components in the DataPlugins property which is a kind of Lazy loader.
The IDataService interface talks to the service layer
The "Entities" folder contains the various entities which the View will understand.Let us look
into one of the entities say "Priority"
using System.Runtime.Serialization;
namespace TMSService.Entities
{
[DataContract]
public class Priority
{
[DataMember]
The other entities follow the same pattern.The data once received from the TMSDataService will
be converted by the "Adaptor".The below is an example for the Adaptor to convert the EF
tblPriority entity to the custom Priority collection.
public List GetPriority()
{
//Obtain the data from Adaptee
var lstPriorityData = adaptee.GetPriority();
var lstPriorities = new List();
//Do the transformation
foreach (tblPriority p in lstPriorityData)
{
lstPriorities.Add(new Priority
{
PriorityID = p.PriorityID
, PriorityName = p.PriorityName
});
}
return lstPriorities;
}
The "Adaptee" is the guy who will perform the interaction between these two layers.The service
layer exposes it's services to the client through the "ITMSService" interface which has the
following operations to offer
It is the TmsClientService that interacts with the WCF service.So the client code(partial) is as
under for obtaining the collection of "Priorities"
public List GetPriority()
{
using (TmsServiceClient client = new TmsServiceClient())
{
try
{
return client.GetPriority();
}
catch (Exception)
{
client.Abort();
throw;
}
}
}
The "Create Task" screen looks as under where the users will give the assignments to their
resources
Clicking on the "View Task" menu, will take us to the dashboard where the managers can figure
out the vaious tasks assigned to the resources, the estimated time and actual time taken for the
task completion etc.
Conclusion
In this short article we have seen how to make a scalable 3-Tire application using
MEF,EF,WCF,ASP.net technologies.Hope this will help the beginners to start with.