sexta-feira, 19 de setembro de 2014

Excel + C# - Let's Play with it!

Programar no Office está cada vez melhor, graças as bibliotecas OpenXML. Vamos brincar um pouco com a criação e manipulação de um arquivo Excel.

Primeiro vamos baixar a biblioteca OpenXML (2.0) e adicioná-la no Visual Studio

Baixe o instalador Open XML SDK 2.0 for Microsoft Office. Baixe os dois arquivos [msi], sendo que usaremos no VS o arquivo OpenXMLSDKv2.msi .

Eu já expliquei um pouco o uso desta tecnologia aqui.

Vamos então criar um novo projeto no VS (CONSOLE Application) e adicionar a referência da biblioteca [DocumentFormat.OpenXml] como ilustrado na figura abaixo



Para criar o arquivo Excel, utilize a seguinte função especificada abaixo. Não esqueça antes as seguintes referências no código:


using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;



private static void CriarTemplate(string template)
{
 using (var doc = SpreadsheetDocument.Create(template, SpreadsheetDocumentType.Workbook))
 {
  doc.AddWorkbookPart().AddNewPart<WorksheetPart>().Worksheet = new Worksheet(new SheetData());

  WorkbookStylesPart stylesPartDef = doc.WorkbookPart.AddNewPart<WorkbookStylesPart>();
  stylesPartDef.Stylesheet = GenerateStyleSheet();
  stylesPartDef.Stylesheet.Save();

  doc.WorkbookPart.Workbook =
    new Workbook(
   new Sheets(
     new Sheet
     {
      Id = doc.WorkbookPart.GetIdOfPart(doc.WorkbookPart.WorksheetParts.First()),
      SheetId = 1,
      Name = "Sheet1"
     }));

  string relId = doc.WorkbookPart.Workbook.Descendants<Sheet>().First().Id;
  var wSheetPart = (WorksheetPart)doc.WorkbookPart.GetPartById(relId);

  //var mergeCells = new MergeCells();
  //wSheetPart.Worksheet.InsertAfter(mergeCells, wSheetPart.Worksheet.Elements<SheetData>().First());
 }
}


Faça a chamada do método CriarTemplate para criar o arquivo excel


static void Main(string[] args)
{
 string template = @"C:\TEMP\Test.xlsx";
 CriarTemplate(template);
}


Com isto já podemos manipular o template. Vamos abrí-lo e criar um conteúdo simples na célula [A1]


private static void ManipularTemplate(string template)
{
 using (SpreadsheetDocument documento = SpreadsheetDocument.Open(template, true))
 {
  var wBookPart = documento.WorkbookPart;
  string relId = wBookPart.Workbook.Descendants<Sheet>().First().Id;
  var wSheetPart = (WorksheetPart)wBookPart.GetPartById(relId);

  // CRIA A LINHA 1 COM MERGE DE COLUNAS (1 a 10)...
  var rowIndex = 1;
  var row = new Row() { RowIndex = UInt32.Parse(rowIndex.ToString()) };
  row.Append(CreateCell(1, rowIndex, 0, CellValues.String, "LINHA 1"));
  wSheetPart.Worksheet.First().AppendChild(row);

  //fnMergeCells(wSheetPart, rowIndex, 1, 10);

  wSheetPart.Worksheet.Save();
 }
}


Adicione as classes de apoio, para criação da célula, merge de células e conversão de número de coluna em letras.



private static Cell CreateCell(int colIndex, int rowIndex, int styleIndex, CellValues cellValues, string cellValueText)
{
 var cell = new Cell() { CellReference = getCellReference(colIndex) + rowIndex.ToString(), StyleIndex = (UInt32Value)(UInt32)styleIndex, DataType = cellValues };
 var cellValue = new CellValue();
 cellValue.Text = cellValueText;
 cell.Append(cellValue);
 return cell;
}

private static void fnMergeCells(WorksheetPart wSheetPart, int rowIndex, int de_Min, int ate_Max)
{
 var mergeCell = new MergeCell() { Reference = new StringValue(getCellReference(de_Min) + rowIndex.ToString() + ":" + getCellReference(ate_Max + 1) + rowIndex.ToString()) };

 var mergeCells = wSheetPart.Worksheet.Elements<MergeCells>().First();
 mergeCells.Append(mergeCell);

 wSheetPart.Worksheet.Save();
}

private static StringValue getCellReference(int colIndex)
{
 string columnString = "";
 decimal columnNumber = colIndex;
 while (columnNumber > 0)
 {
  decimal currentLetterNumber = (columnNumber - 1) % 26;
  char currentLetter = (char)(currentLetterNumber + 65);
  columnString = currentLetter + columnString;
  columnNumber = (columnNumber - (currentLetterNumber + 1)) / 26;
 }
 return columnString;
}

private static Stylesheet GenerateStyleSheet()
{
 var styleSheet = new Stylesheet();

 var fonts = new Fonts();
 var fontDef = new Font(
      new FontSize() { Val = 11 },
      new Color() { Rgb = new HexBinaryValue() { Value = "000000" } },
      new FontName() { Val = "Calibri" });

 fonts.Append(fontDef);

 var fills = new Fills(
     new Fill(
      new PatternFill() { PatternType = PatternValues.None }
     ),
     new Fill(
      new PatternFill() { PatternType = PatternValues.Gray125 }
     ),
  // BLUE COLOR
     new Fill(
      new PatternFill(
       new ForegroundColor() { Theme = (UInt32Value)4U, Tint = 0.39997558519241921D },
       new BackgroundColor() { Indexed = (UInt32Value)64U }
      ) { PatternType = PatternValues.Solid }
     )
    );

 var borders = new Borders(
      new Border(new LeftBorder(), new RightBorder(), new TopBorder(), new BottomBorder(), new DiagonalBorder())
      );

 // CellFormats IS THE CLASS USED IN THE PROPERTIES [StyleIndex] FOR ALL OBJECTS
 var cellFormats = new CellFormats(
  // StyleIndex[0] - Default
       new CellFormat() { FontId = 0, FillId = 0, BorderId = 0 },
  // StyleIndex[1] - FONT BLUE
       new CellFormat() { FontId = 0, FillId = 2, BorderId = 0, ApplyFill = true }
       );

 styleSheet.Append(fonts);
 styleSheet.Append(fills);
 styleSheet.Append(borders);
 styleSheet.Append(cellFormats);

 return styleSheet;
}


Efetue a chamada do método ManipularTemplate


static void Main(string[] args)
{
 string template = @"C:\TEMP\Test.xlsx";
 CriarTemplate(template);
 ManipularTemplate(template);
}


Não se esqueça de adicionar outra referência importante no projeto, a dll WindowsBase



Execute o projeto e terá como resultado (o projeto cria o arquivo em c:\temp)



Agora vamos trabalhar com merge e estilo de células. Vamos efetuar o merge das 10 primeiras células e pintá-la de azul. Primeiro, altere o método [Manipular Template] e altere a linha de


row.Append(CreateCell(1, rowIndex, 0, CellValues.String, "LINHA 1"));

PARA 


row.Append(CreateCell(1, rowIndex, 1, CellValues.String, "LINHA 1"));


Note que a diferença está no terceiro valor do parâmetro da função [CreateCell]. Ela indica qual StyleIndex usar. Para que serve o StyleIndex? Justamente para indicar qual Estilo aplicar na célula. Onde ficam estes estilos? Quando criamos o método [CriarTemplate] já especificamos os estilos na criação do arquivo, na linha


stylesPartDef.Stylesheet = GenerateStyleSheet();
stylesPartDef.Stylesheet.Save();


Analise o método GenerateStyleSheet. Nele criamos todos os estilos necessários como tipo de fonte, preenchimento e borda. Porém ainda precisamos reunir todos estes estilos para aplicar na StyleIndex das células. Por exemplo, eu preciso de um fonte Bold, da célula com preenchimento azul, da célula com borda, etc. Como fazer isto? Apenas use a classe [CellFormats]. Ela junta tudo para você, de forma que você pode criar quantas CellFormats forem necessárias. No nosso exemplo criamos os seguintes CellFormats


var cellFormats = new CellFormats(
 // StyleIndex[0] - Default
      new CellFormat() { FontId = 0, FillId = 0, BorderId = 0 },
 // StyleIndex[1] - FONT BLUE
      new CellFormat() { FontId = 0, FillId = 2, BorderId = 0, ApplyFill = true }
      );


Vamos aplicar agora o recurso de merge. Entre no método [ManipularTemplate] e habilite a seguinte linha comentada


fnMergeCells(wSheetPart, rowIndex, 1, 10);


Entre também no método [CriarTemplate] e habilite as linhas


var mergeCells = new MergeCells();
wSheetPart.Worksheet.InsertAfter(mergeCells, wSheetPart.Worksheet.Elements<SheetData>().First());


E o resultado agora



That's It!
[]s

quarta-feira, 27 de agosto de 2014

Reporting Services - Girar Imagem usando VB.NET

Um recurso interessante do reporting services é a possibilidade de execução de código VB.NET no seu relatório. Com isto em mãos podemos resolver inúmeras situações com pouco código. Imagine então a situação em que você possui uma imagem para ser adicionada no seu relatório. Porém o cliente precisa que esta imagem seja visualizada em um grau diferente, como por exemplo, na vertical. Não existe uma propriedade do componente de imagem na qual possa ser configurada esta alteração. Felizmente, via programação, resolvemos isto de forma bem simples, conforme mostrado abaixo.

Primeiro, vamos adicionar a referência da classe Drawing no relatório (opção Propriedades)



E vamos adicionar nosso código para girar a imagem




Function GirarImagem(ByVal imageDB As Byte()) As Byte()

        Dim ms As System.IO.Stream = New System.IO.MemoryStream(imageDB)
        ms.Seek(0, System.IO.SeekOrigin.Begin)

        Dim imgObj As System.Drawing.Bitmap = New System.Drawing.Bitmap(ms)
        imgObj.RotateFlip(System.Drawing.RotateFlipType.Rotate270FlipXY)

        Dim ms2 As System.IO.MemoryStream = New System.IO.MemoryStream()
        imgObj.Save(ms2, System.Drawing.Imaging.ImageFormat.Bmp)
        Dim bitmapData As Byte() = ms2.ToArray()

        Return bitmapData

End Function


Note que a função espera um parâmetro de imagem do tipo [Byte()], pois neste nosso exemplo o relatório busca a imagem como um campo no banco de dados (VarBinary)



Desta forma, vamos alterar a expressão do objeto de imagem para executar nossa função



E o resultado



Ref: Rotate Flip Types

[]s

terça-feira, 19 de agosto de 2014

JQuery AutoComplete - IE Performance

Um dos mais úteis componentes da lista do JQuery UI sem dúvida é o AutoComplete. Porém, existe um problema conhecido de performance ao usar este componente no [Internet Explorer] quando a lista de informações passa de 1000 registros.

Observando mais de perto este problema podemos perceber que no IE a [renderização] dos dados é a causa do problema e não a quantidade de informações da lista em si.

Desta forma, se você estiver passando por este problema no IE poderá alterar o atributo [source] do componente para executar uma função específica criada por você para justamente [limitar] a quantidade de dados de retorno que será renderizada no Browser.

Segue um exemplo:

No momento da transformação do seu TextBox em um Lookup, adicione a chamada da sua função (CustomAutoCompleteFn)


with ($("#TEXTBOXID")) {
        autocomplete({
            source: function (reg, responseFn) { CustomAutoCompleteFn(reg, responseFn) },
            delay: 0,
            minLength: 2
        });
}


E a função em si:


function CustomAutoCompleteFn(req, responseFn) {
    // LIMITANDO A LISTA DE RESULTADOS POR RETORNAR OS 40 PRIMEIROS
    var b = new Array();
    var re = $.ui.autocomplete.escapeRegex(req.term);
    var matcher = new RegExp("\\b" + re, "i");
    var a = $.grep(listInfo, function (item, index) {
        r = matcher.test(item.value);
        return r;
    });
    b = a.slice(0, 40);
    responseFn(b);
}


O interessante desta função é que você mesmo efetua o filtro no seu Array de informações (var listInfo) e retorna para ser renderizado no Browser apenas a quantidade que deseja, através da linha [b = a.slice(0, 40)].

Desta forma sua performance fica garantida mesmo com uma lista de informações extensa.

Fonte: JQuery Forum

[]

terça-feira, 8 de julho de 2014

Free Microsoft eBooks!

Uma boa novidade vinda de Redmond! A Microsoft liberou centenas de livros gratuitos para download, através do artigo publicado por Eric Ligman (Microsoft Senior Sales Excellence Manager).

Entre eles se destacam:




Windows 8.1
Windows 8
Windows 7
Office 2013
Office 365
Office 2010
SharePoint 2013
Dynamics CRM
PowerShell
Exchange Server
Lync 2013
Azure
SQL Server

e muito mais!

Boa leitura!!

Fonte: Microsoft Senior Sales Excellence Manager - Eric Ligman

quarta-feira, 23 de abril de 2014

Dependency Injection (DI) in ASP.NET MVC

Quem desenvolve para MVC percebe que um dos recursos mais importantes é o padrão que nos habilita a usar o [SoC] - Separation of Concerns.

Nós queremos que os componentes de nossa aplicação sejam os mais independentes possíveis uns dos outros (além de efetuarmos testes e manutenção na aplicação de forma mais fácil), sendo que numa situação ideal, um componente não deveria saber da existência de outro, apenas terem uma ligação fraca uns com os outros (loose coupling) através do uso de [Interfaces].


Por exemplo, se criarmos duas classes com a necessidade de ligação fraca entre elas, a criação de uma interface nos ajuda neste sentido:




public class PasswordResetHelper {
public void ResetPassword() {
   IEmailSender mySender = new MyEmailSender();
   //...call interface methods to configure e-mail details...
   mySender.SendEmail();
   }
}

Mas como você deve ter notado no código acima, ainda temos um problema!...não existe um recurso padrão do C# para implementarmos o uso da interface [IEmailSender] sem a criação de uma instância da classe [MyEmailSender].

Portanto, mesmo usando uma Interface, ainda temos uma ligação de qualquer maneira...



Existe uma solução para isto? Sim, e se chama DI - Dependency Injection!

Uma forma rápida para melhorar o código acima seria a criação de um [construtor] e nele passaríamos a implementação da interface somente para a classe [PasswordResetHelper]


public class PasswordResetHelper {
   private IEmailSender emailSender;

   public PasswordResetHelper(IEmailSender emailSenderParam) {
   emailSender = emailSenderParam;
   }

   public void ResetPassword() {
   // ...call interface methods to configure e-mail details...
   emailSender.SendEmail();
   }
}

Com isto conseguimos quebrar a dependência entre as classes [PasswordResetHelper] e [MyEmailSender]. O que acabamos de fazer se chama [Constructor Injection].

Agora, para melhorarmos ainda mais nosso projeto MVC, podemos e devemos utilizar ferramentas sólidas para o tratamento de [DI]. Para tanto, existem algumas no mercado, como a Unit da Microsoft e NInject, a qual será usada neste artigo.

Criando as Classes de Controle

Vamos criar um novo projeto no Visual Studio, clicando em Novo -> Projeto -> [ASP.NET MVC 4 Web Application] Template e selecione a opção [Empty] para criar o projeto sem conteúdo. Dê o nome para o projeto de [EssentialTools].

A seguir, adicione a seguinte classe na pasta Models do projeto, com o nome Product.cs:


namespace EssentialTools.Models {
   public class Product {
   public int ProductID { get; set; }
   public string Name { get; set; }
   public string Description { get; set; }
   public decimal Price { get; set; }
   public string Category { set; get; }
   }
}

Também adicione na pasta Models uma classe para efetuar um cálculo na coleção de produtos, com o nome [LinqValueCalculator]


using System.Collections.Generic;
using System.Linq;

namespace EssentialTools.Models {
      public class LinqValueCalculator {
      public decimal ValueProducts(IEnumerable<Product> products) {
      return products.Sum(p => p.Price);
      }
   }
}


Agora crie a outra classe (ShoppingCart) que se relaciona com a criada anteriormente


using System.Collections.Generic;

namespace EssentialTools.Models {
   public class ShoppingCart {
      private LinqValueCalculator calc;
      
      public ShoppingCart(LinqValueCalculator calcParam) {
         calc = calcParam;
      }

      public IEnumerable<Product> Products { get; set; }
      public decimal CalculateProductTotal() {
         return calc.ValueProducts(Products);
      }
   }
}


Adicionando um Controller

Adicione um controller na pasta Controllers chamado HomeController e altere o seu conteúdo para o proposto abaixo


using EssentialTools.Models;
using System.Web.Mvc;
using System.Linq;

namespace EssentialTools.Controllers {
public class HomeController : Controller {
   private Product[] products = {
   new Product {Name = "Kayak", Category = "Watersports", Price = 275M},
   new Product {Name = "Lifejacket", Category = "Watersports", Price = 48.95M},
   new Product {Name = "Soccer ball", Category = "Soccer", Price = 19.50M},
   new Product {Name = "Corner flag", Category = "Soccer", Price = 34.95M}
   };

   public ActionResult Index() {
      LinqValueCalculator calc = new LinqValueCalculator();
      ShoppingCart cart = new ShoppingCart(calc) { Products = products };
      decimal totalValue = cart.CalculateProductTotal();
      return View(totalValue);
   }
}
}


Note que estamos usando este controller para testar nossas classes [LinqValueCalculator] e [ShoppingCart]

Adicionando uma View

Adicione uma View para visualizar o resultado do controler. Clique com o botão direito na ação Index da HomeController e selecione [Add View] e crie uma View chamada [Index], modificando o conteúdo conforme o proposto abaixo


@model decimal
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Value</title>
</head>
<body>
<div>
Total value is $@Model
</div>
</body>
</html>


Neste ponto, execute a aplicação e veja se tudo está rodando corretamente, apresentando a tela abaixo



Usando Ninject

Até o momento criamos duas classes com acoplamento forte (tightly-coupled), na qual ShoppingCart está ligada a classe LinqValueCalculator, e a HomeController ligada as duas. Pensando na manutenção disto em um projeto real podemos imaginar que será complicado, pois, por exemplo, se alterarmos o uso da classe [LinqValueCalculator] por outra, teremos que trocar a referência desta classe no projeto.

Vamos então aplicar primeiramente a Interface, que resolve parte do processo de acoplagem. Crie uma classe chamada [IValueCalculator] na pasta [Models] com o seguinte conteúdo:


using System.Collections.Generic;

namespace EssentialTools.Models {
   public interface IValueCalculator {
      decimal ValueProducts(IEnumerable<Product> products);
   }
}


Com isto podemos agora implementar esta interface na classe [LinqValueCalculator]


using System.Collections.Generic;
using System.Linq;

namespace EssentialTools.Models {
   public class LinqValueCalculator: IValueCalculator {
      public decimal ValueProducts(IEnumerable<Product> products) {
         return products.Sum(p => p.Price);
      }
   }
}


Com isto quebramos a ligação forte entre as classes ShoppingCart e LinqValueCalculator


using System.Collections.Generic;

namespace EssentialTools.Models {
 public class ShoppingCart {
  private IValueCalculator calc;
  
  public ShoppingCart(IValueCalculator calcParam) {
   calc = calcParam;
  }
  public IEnumerable<Product> Products { get; set; }
  
  public decimal CalculateProductTotal() {
   return calc.ValueProducts(Products);
  }
 }
}


Fizemos progresso, porém o C# ainda requer que implementemos a classe [LinqValueCalculator] na nossa HomeController, o que é ruim pois ainda estaremos ligando fortemente as classes


...
public ActionResult Index() {
 IValueCalculator calc = new LinqValueCalculator();
 ShoppingCart cart = new ShoppingCart(calc) { Products = products };
 decimal totalValue = cart.CalculateProductTotal();
 return View(totalValue);
}
...


Para desacoplar de uma vez este processo usaremos então Ninject mantendo também nossa HomeController somente com a implementação de uma Interface

Adicionando Ninject no Visual Studio

A forma mais fácil é o uso do recurso integrado ao VS, o NuGet, abrindo primeiro seu projeto, depois selecionando o menu Tools - > NuGet Package Manager -> Manage NuGet Packages for Solution



Na opção [Online] do Nuget, busque pela palavra [ninject]. Clique no botão install para adicionar as bibliotecas do Ninject no seu projeto. Podemos agora utilizar este recurso em nossa HomeController, conforme mostrado abaixo


using EssentialTools.Models;
using System.Web.Mvc;
using System.Linq;
using Ninject;

namespace EssentialTools.Controllers {
 public class HomeController : Controller {
  private Product[] products = {
  new Product {Name = "Kayak", Category = "Watersports", Price = 275M},
  new Product {Name = "Lifejacket", Category = "Watersports", Price = 48.95M},
  new Product {Name = "Soccer ball", Category = "Soccer", Price = 19.50M},
  new Product {Name = "Corner flag", Category = "Soccer", Price = 34.95M}
  };

  public ActionResult Index() {
   IKernel ninjectKernel = new StandardKernel();
   ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
   IValueCalculator calc = ninjectKernel.Get<IValueCalculator>();
   
   ShoppingCart cart = new ShoppingCart(calc) { Products = products };
   decimal totalValue = cart.CalculateProductTotal();
   
   return View(totalValue);
  }
 }
}


O primeiro estágio é o preparo para uso do Ninject, através da instância da classe [StandardKernel]. Com isto conseguimos criar um relacionamento entre as interfaces em nossa aplicação e as classes de implementação que nós queremos trabalhar. Você notou isto quando foi executado o passo descrito abaixo


...
ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
...


E como passo final o uso do Ninject para obter a implementação da Interface que queremos


...
IValueCalculator calc = ninjectKernel.Get<IValueCalculator>();
...


a este ponto você pode se perguntar, eu ainda possuo uma ligação forte entre meu Controller e a classe [LinqValueCalculator]...e é verdade. Porém, fácil de resolver pois podemos atuar no [core] do MVC adicionando o Kernel do Ninject no processo interno do MVC, de forma a desacoplar de uma vez por todas nossas classes da HomeController.

Criando um Dependency Resolver

Este recurso é interessante pois vamos adicionar nossas resoluções de classes x interfaces, no [core] do MVC, criando uma classe [resolver] que será instanciada na inicialização do projeto, por configurá-la no arquivo [Global.asax.cs] do projeto. Como passo final, alteramos nossa HomeController para usar somente a interface que desejamos. Veja todos estes passos em sequência:

1 - Adicione uma nova pasta chamada [Infrastructure] no projeto e crie uma classe chamada [NinjectDependencyResolver] com o conteúdo abaixo:


using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Ninject;
using Ninject.Parameters;
using Ninject.Syntax;
using System.Configuration;
using EssentialTools.Models;

namespace EssentialTools.Infrastructure {
 public class NinjectDependencyResolver : IDependencyResolver {
  private IKernel kernel;
  
  public NinjectDependencyResolver() {
   kernel = new StandardKernel();
   AddBindings();
  }
  
  public object GetService(Type serviceType) {
   return kernel.TryGet(serviceType);
  }
  
  public IEnumerable<object> GetServices(Type serviceType) {
   return kernel.GetAll(serviceType);
  }
  
  private void AddBindings() {
   kernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
  }
 }
}


2 - Registre a classe Dependency Resolver no Global.asax.cs (no método Application_Start)


using EssentialTools.Infrastructure;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;

namespace EssentialTools {
 public class MvcApplication : System.Web.HttpApplication {
  protected void Application_Start() {
   AreaRegistration.RegisterAllAreas();
   
   DependencyResolver.SetResolver(new NinjectDependencyResolver());
   
   WebApiConfig.Register(GlobalConfiguration.Configuration);
   FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
   RouteConfig.RegisterRoutes(RouteTable.Routes);
  }
 }
}


3 - Refatore sua HomeController


using EssentialTools.Models;
using System.Web.Mvc;
using System.Linq;

namespace EssentialTools.Controllers {
 public class HomeController : Controller {
  private Product[] products = {
  new Product {Name = "Kayak", Category = "Watersports", Price = 275M},
  new Product {Name = "Lifejacket", Category = "Watersports", Price = 48.95M},
  new Product {Name = "Soccer ball", Category = "Soccer", Price = 19.50M},
  new Product {Name = "Corner flag", Category = "Soccer", Price = 34.95M}
  };

  private IValueCalculator calc;
  public HomeController(IValueCalculator calcParam) {
   calc = calcParam;
  }

  public ActionResult Index() {
   ShoppingCart cart = new ShoppingCart(calc) { Products = products };
   decimal totalValue = cart.CalculateProductTotal();
   return View(totalValue);
  }
 }
}


That's it!!

Ref: Pro ASP.NET MVC 4 - 4th Edition - Adam Freeman, aPress