Mi sono chiesto per un po 'di tempo su alcuni problemi durante l'utilizzo di Injection dipendenza:
In un'applicazione a livelli, di solito inserisco i repository nel servizio dell'applicazione utilizzando l'iniezione del costruttore:
public class SomeService
{
private IRepositoryA _repoA;
private IRepositoryB _repoB;
private IRepositoryC _repoC;
public SomeService(IRepositoryA repositoryA,
IRepositoryB repositoryB,
IRepositoryC repositoryC
/* Other dependencies*/)
{
_repoA = repositoryA;
_repoB = repositoryB;
_repoC = repositoryC;
}
public void SomeMethod1()
{
//Do something with repo A and B
}
public void SomeMethod2()
{
//Do something with repo C
}
//Other methods
}
I problemi con questo sono:
-
Quando il servizio diventa complicato, il numero di dipendenze aumenterà sempre di più e presto il costruttore diventerà brutto con molti parametri. Potrebbe essere che il servizio stia facendo troppe cose (violare SRP) e sia meglio dividerlo in più classi, ma penso che questa situazione non sia rara quindi sono curioso di sapere come gli altri risolvono questo
-
SomeMethod1 () utilizza solo repo A e B, ma quando il client lo chiama, il servizio viene creato con tutti i repository, il che significa che ha più dipendenze del necessario.
Per risolvere questi due problemi, vedo che alcune persone hanno un'altra astrazione, che è una fabbrica di repository
public interface IRepositoryFactory
{
T GetRepository<T>() where T : IRepository;
}
public class RepositoryFactory
{
public T GetRepository<T>()
{
//Use IoC to return correct IRepository
}
}
e inserisci la fabbrica nella classe di servizio:
public class SomeService
{
private IRepositoryFactory _factory;
public SomeService(IRepositoryFactory factory)
{
_factory = factory;
}
public void SomeMethod1()
{
IRepositoryA repoA = _factory.GetRepository<IRepositoryA>();
IRepositoryB repoB = _factory.GetRepository<IRepositoryB>();
//Use repo A and B
}
public void SomeMethod2()
{
IRepositoryC repoC = _factory.GetRepository<IRepositoryC>();
//Use repo C
}
//Other methods
}
Questo risolve i 2 problemi di cui sopra, ma ci sono alcuni altri problemi:
- RepositoryFactory utilizza IoC come un servizio di localizzazione, considerato da molti come anti-pattern
- RepositoryFactory ora ha una dipendenza dal framework IoC, che potrebbe essere indesiderabile nell'integrazione delle dipendenze (perché, come ho capito, l'applicazione dovrebbe avere il minimo di comprensione sull'IoC come possono, tranne per la composizione root, che è in cima a l'applicazione)
Quindi questo è un buon approccio da usare?