Integrando sua aplicação com o TFS 2010

Quando estamos trabalhando com o Team Foundation Server podemos realizar varias customizações, porém algumas vezes precisamos algo específico como fazer que uma aplicação externa acesse as informações do TFS. Para isso a Microsoft disponibilizou uma API para que possamos se conectar ao TFS e fazer algumas operações com Projects, Work Items, etc.

Hoje vamos ver como podemos fazer com que uma aplicação ASP NET MVC possa criar e pesquisar WorkItems no TFS

Primeiro de tudo temos que adicionar as referências para as seguintes DLLs

  • Microsoft.TeamFoundation.dll
  • Microsoft.TeamFoundation.Client.dll
  • Microsoft.TeamFoundation.WorkItemTracking.Client.dll

Agora vamos criar uma classe chamada TFS2010 e vamos implementar alguns métodos

1 – Criar Work Item

O primeiro método é para criar um novo WorkItem, veja abaixo o código

[sourcecode language=”csharp”]
public static NetworkCredential TFSCredentials
{
get
{
return new NetworkCredential("TFS_USER", "TFS_PASS", "TFS_DOMAIN");
}
}

public static int Create(string collection, string projeto, string tipo, string titulo, string responsavel, string descricao, string prioridade, Attachment anexo)
{
try
{
// Conecta ao TFS
Uri tfsUri = new Uri(collection);

// Recupera os projetos daquela Collection passando comom parametro as credenciais
using (TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(tfsUri, TFS2010.TFSCredentials))
{
// Recupera o projeto especifico
WorkItemStore workItemStore = tpc.GetService();
Project teamProject = workItemStore.Projects[projeto];

// Criar o novo Work Item conforme o tipo (Bug, Task, etc…)
WorkItem wi = new WorkItem(teamProject.WorkItemTypes[tipo]);

// Titulo do WI
wi.Title = titulo;

// Descriçãa do WI
wi.Fields["Description"].Value = descricao;

// Resposnsavel pelo WI
wi.Fields["Assigned To"].Value = responsavel;

// Prioridade do WI
wi.Fields["Priority"].Value = prioridade;

// Veirfica se o WI possui um anexo
if (anexo != null)
{
// Adiciona o anexo ao WI
wi.Attachments.Add(anexo);
}

// Salva o WI
wi.Save();

// Retorna o número do WI
return wi.Id;
}
}
catch (Exception ex)
{
throw (ex);
}
}
[/sourcecode]

O código acima não tem segredo, conectamos no TFS depois recuperamos o projeto em questão e criamos um novo WI para aquele projeto, o código está todo comentado para facilitar o entendimento.

Agora vamos chamar esse método para criar o WI, vamos criar um controller com o nome de ChamadosController que vai ter uma action Novo, veja abaixo.

[sourcecode language=”csharp”]
[HttpPost]
public ActionResult Novo(IntegracaoTFS2010.Models.WorkItem model)
{
if (ModelState.IsValid)
{
int idWorkItem = TFSUtil.TFS2010.Create(
"http://tfs-2010:8080/tfs/DefaultCollection",
"ProjetoCMMI",
model.tipo,
model.titulo,
model.responsavel,
model.descricao,
model.prioridade);

if (idWorkItem > 0)
return RedirectToAction("Index");
}

return View(model);
}
[/sourcecode]

Vamos chamar a nossa tela e criar um novo WorkItem

Veja o WorkItem criado no TFS

2 – Listar WorkItem

Agora vamos criar outro método para listar os Work Items que gravamos no TFS, veja abaixo o código

[sourcecode language=”csharp”]
public static WorkItemCollection ListWorkItem(string collection, string projeto, string tipo)
{
try
{
// Set up a dictionary to pass "User Story" as the value of the type variable.
Dictionary variables = new Dictionary();

Query queryResult;

// Conecta ao TFS
Uri tfsUri = new Uri(collection);

// Recupera os projetos daquela Collection passando comom parametro as credenciais
using (TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(tfsUri, TFS2010.TFSCredentials))
{
// Recupera o projeto especifico
WorkItemStore workItemStore = tpc.GetService();

// String para criar a query
StringBuilder query = new StringBuilder();
query.Append(" Select [State], [Title] ");
query.Append(" From WorkItems ");

if (!String.IsNullOrEmpty(tipo))
{
query.Append(" Where [Work Item Type] = @Type");
variables.Add("Type", tipo);
}

query.Append(" Order By [State] Asc, [Changed Date] Desc");

// Cria uma nova query
if (!String.IsNullOrEmpty(tipo))
queryResult = new Query(workItemStore, query.ToString(), variables);
else
queryResult = new Query(workItemStore, query.ToString());

// Executa a query
WorkItemCollection results = queryResult.RunQuery();
return results;
}
}
catch (Exception ex)
{
throw (ex);
}
}
[/sourcecode]

Veja que a sintax é do SQL ANSI e também podemos adicionar vários parâmetros na cláusula WHERE e ordenar na cláusula ORDER BY

Agora vamos chamar esse método para listas os WIs, em nosso controller ChamadosController na action Index, veja abaixo.

[sourcecode language=”csharp”]
using TFS = Microsoft.TeamFoundation.WorkItemTracking.Client;

public ActionResult Index()
{
TFS.WorkItemCollection listWI = TFSUtil.TFS2010.ListWorkItem(
"http://tfs-2010:8080/tfs/DefaultCollection",
"ProjetoCMMI",
"Task");

List lst = new List();

foreach (TFS.WorkItem item in listWI)
{
Models.WorkItem model = new Models.WorkItem();
model.Id = item.Id;
model.tipo = item.Type.Name;
model.titulo = item.Title;
model.responsavel = item.Fields["Assigned To"].Value.ToString();
model.descricao = item.Fields["Description"].Value.ToString();
model.prioridade = item.Fields["Priority"].Value.ToString();
model.DataCriacao = item.CreatedDate;
lst.Add(model);
}

return View(lst);
}
[/sourcecode]

Vamos chamar a nossa tela de listagem

Podemos perceber que não é muito difícil integrar sua aplicação com o TFS, basta estudar a biblioteca, para mais informações acessem os links abaixo:

http://msdn.microsoft.com/en-us/library/dd470570.aspx

http://msdn.microsoft.com/en-us/library/bb130306.aspx

Faça o Download desse projeto de exemplo no link abaixo

Download do Projeto

Qualquer dúvida, opinião, reclamação mande seu comentário!

Aquele Abraço!

Sobre Leandro Prado

Leandro Silveira Prado é Premier Field Engineer na Microsoft especializado em Application Lifecycle Management.