...
Existem muitas estruturas/frameworks de injeção de dependência que automatizam a resolução de dependências. Eles podem criar objetos com todas as dependências (e dependências de dependências recursivamente). Então, basta escrever sua classe com padrões de injeção de construtor e/ou propriedades que o framework de DI lida com o resto! Em uma boa aplicação, suas classes são independentes mesmo do framework DI. Haverá algumas linhas de código ou classes que interagem explicitamente com o framework DI em toda a sua aplicação. O TNF usa a estrutura do Castle Windsor para Injeção de Dependência. É um dos Frameworks de DI mais maduros. Existem muitos outros frameworks como Unity, Ninject, StructureMap, Autofac e assim por diante.
public class PersonAppService
{
private IPersonRepository _personRepository;
public PersonAppService(IPersonRepository personRepository)
{
_personRepository = personRepository;
}
public void CreatePerson(string name, int age)
{
var person = new Person { Name = name, Age = age };
_personRepository.Insert(person);
}
}
...
container.Register(
Component.For<IPersonRepository>().ImplementedBy<PersonRepository>().LifestyleTransient(),
Component.For<IPersonAppService>().ImplementedBy<PersonAppService>().LifestyleTransient()
);
var personService = container.Resolve<IPersonAppService>();
personService.CreatePerson("Yunus Emre", 19);
...
O TNF quase torna invisível o uso da estrutura de injeção de dependência ao escrever sua aplicação seguindo as práticas recomendadas e algumas convenções.
...
O TNF registra automaticamente todos os Repositórios, Serviços de Domínio, Serviços de Aplicação, Controladores MVC e Controladores da Web API por convenção. Por exemplo, você pode ter uma interface IPersonAppService e uma classe PersonAppService que implementa:
...
Toda classe registrada no injetor de DI pode ser resolvida automaticamente através da injeção pelo construtor de uma classe ou usando o objeto de IocManager do TNF:
...
Existem cenários onde é necessário cria criar uma instancia e após seu uso realizar sua liberação. Para esses casos o objeto de IocManager possui métodos de extensão que possibilitam a criação e a liberação desses recursos:
public class MySampleClass : ITransientDependency
{
private readonly IIocResolver _iocResolver;
public MySampleClass(IIocResolver iocResolver)
{
_iocResolver = iocResolver;
}
public void DoIt()
{
// Resolving, using and releasing manually
var personService1 = _iocResolver.Resolve<PersonAppService>();
personService1.CreatePerson(new CreatePersonInput { Name = "Yunus", Surname = "Emre" });
_iocResolver.Release(personService1);
// Resolving and using in a safe way
using (var personService2 = _iocResolver.ResolveAsDisposable<PersonAppService>())
{
personService2.Object.CreatePerson(new CreatePersonInput { Name = "Yunus", Surname = "Emre" });
}
}
}
No cenário acima foi realizada a injeção do objeto IIocResolver. O mesmo cenário pode ser criado usando diretamente o objeto IocManager como no exemplo abaixo:
...
public class MySampleClass : ITransientDependency
{
public void DoIt()
{
// Resolving, using and releasing manually
var personService1 = IocManager.Instance.Resolve<PersonAppService>();
personService1.CreatePerson(new CreatePersonInput { Name = "Yunus", Surname = "Emre" });
_iocResolver.Release(personService1);
// Resolving and using in a safe way
using (var personService2 = IocManager.Instance.ResolveAsDisposable<PersonAppService>())
{
personService2.Object.CreatePerson(new CreatePersonInput { Name = "Yunus", Surname = "Emre" });
}
}
}
IShouldInitialize interface
Algumas classes precisam ser inicializadas antes da primeira utilização. A interface IShouldInitialize tem um método Initialize(). Se você implementá-lo, então o método Initialize() é chamado automaticamente apenas após a criação do objeto (antes usado).
...