Ok, então você começou a usar o Dependency Injection e viu que dava muito trabalho. A boa notícia é que existem vários frameworks por aí que ajudam a diminuir o trabalho e ainda a ter um código muito mais limpo.
Particularmente, eu gosto muito do StructureMap, principalmente porque ele nos permite utilizar o “Convention over Configuration”. Vamos ver jajá como isso funciona.
Bom, dando sequência no post anterior, vamos modificar aquele código para utilizar o StructureMap. A primeira coisa a fazer obviamente é baixar o framework e adicionar uma referência para o assembly StructureMap.dll.
O próximo passo é configurar o StructureMap, para isso vamos criar uma classe:
public class StructureMapConfiguration
{
public static void Configure()
{
ObjectFactory.Initialize(InitializeStructureMap);
}
private static void InitializeStructureMap(IInitializationExpression x)
{
x.Scan(y =>
{
y.Assembly("MvcApplication1");
y.With();
});
}
}
O que fazemos nesse código e dizer para o ScrutureMap buscar no Assembly MvcApplication1 usando a convenção padrão. E o que é a convenção padrão? Geralmente quando criamos uma interface, como no nosso caso criamos a interface IClienteService criamos uma classe com a implementação padrão da interface chamada ClienteService. Essa é a convenção padrão, dessa forma, toda vez que precisarmos de um objeto que implemente a interface IClienteService o StructureMap buscará nos assemblies informados para ele, a classe de mesmo nome só que sem o I. Prático não? Nada de configurar XMLs e afins (embora o StructureMap permita isso).
Outra coisa que precisamos fazer é criar uma classe que será responsável pela criação dos nosso controllers. Isso é necessário porque por padrão o Asp.Net MVC cria os controllers apenas com o construtor padrão, sem parâmetros. Nossa classe fica assim:
public class StructureMapControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(Type controllerType)
{
if (controllerType == null) return null;
try
{
return ObjectFactory.GetInstance(controllerType) as Controller;
}
catch (StructureMapException)
{
System.Diagnostics.Debug.WriteLine(ObjectFactory.WhatDoIHave());
throw;
}
}
}
Pronto, agora vamos alterar a inicialização da aplicação no Global.asax, que deve ficar assim:
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
StructureMapConfiguration.Configure();
ControllerBuilder.Current.SetControllerFactory(new
StructureMapControllerFactory());
}
Uma última coisa, no nosso controller ClienteController tínhamos dois construtores, agora vamos deixar apenas um com o parâmetro necessário para funcionar:
public IClienteService _service;
public ClienteController(IClienteService service)
{
_service = service;
}
Pronto, isso é tudo o que é necessário. Mas se você quiser utilizar um XML para configurar suas classes, é possível. Dentro da classe de configuração, logo abaixo do método Scan, adicione:
x.AddConfigurationFromXmlFile("structuremap.config.xml");
Isso fará que com que o StructureMap procure na raiz do site por um arquivo chamado structuremap.config.xml. Segue um exemplo de como deve ser esse arquivo:
PluginType="MinhaLibrary.Business.IClasseNegocio, MinhaLibrary.Business" PluggedType="MinhaLibrary.Business.ImplementacaoClasseNegocio, MinhaLibrary.Business" Scope="Singleton" />
É isso! E viva o Convention over Configuration!!!!