Alcune opzioni. Ognuno ha punti di forza e punti deboli.
Inietti un'istanza transitoria
Se si sta utilizzando un contenitore IoC, è possibile registrare una dipendenza come transitoria. Ad esempio, in Ninject puoi usare registerTransient
. Se stai utilizzando Unity, puoi utilizzare TransienLifetimeManager
. Quindi iniettati nella tua classe per normale.
public void CompositionRoot(Container container)
{
container.Register<IValidateCertificate, CertificateValidator>(new TransientLifetimeManager());
container.RegisterType<ICerthandler, CertificadoHandler>(new ContainerControlledLifetimeManager());
}
public class CertificadoHandler : ICertHandler
{
private readonly IValidateCertificate _validateCertificate;
public CertificadoHandler(IValidateCertificate validateCertificate){
_validateCertificate = validateCertificate;
}
public CredentialsData GetCredentialsData(X509Certificate cert)
{
return _validateCertificate.GetCredentialsData(cert);
}
}
Inietta una fabbrica
Potresti iniettare una fabbrica singleton, che permetterà alla classe di istanziare tutto ciò di cui ha bisogno, ma permetterà comunque a un test unitario di sovrascrivere l'iniezione. Il vantaggio dell'utilizzo di una factory (invece di un'istanza transitoria) è che la classe può controllare quando avviene l'istanziazione e può persino fornire gli argomenti del costruttore se necessario.
A seconda del tuo framework IoC, potresti essere in grado di evitare di scrivere la factory e utilizzare invece un factory automatico .
public class ValidateCertificateFactory : IValidateCertificateFactory
{
public IValidateCertificate GetInstance(string constructorArgument)
{
return new ValidateCertificate(constructorArgument);
}
}
public void CompositionRoot(Container container)
{
container.RegisterType<IValidateCertificateFactory, ValidateCertificateFactory>(new ContainerControlledLifetimeManager());
container.RegisterType<ICerthandler, CertificadoHandler>(new ContainerControllerLifetimeManager());
}
public class CertificadoHandler : ICertHandler
{
private readonly IValidateCertificateFactory _validateCertificateFactory;
public CertificadoHandler(IValidateCertificateFactory validateCertificateFactory){
_validateCertificateFactory = validateCertificateFactory;
}
public CredentialsData GetCredentialsData(X509Certificate cert)
{
return _validateCertificateFactory.Resolve("Foo").GetCredentialsData(cert);
}
}
Inietti un delegato
Questo è un po 'come usare una fabbrica ma evita di dover scrivere una classe factory.
public void CompositionRoot(Container container)
{
container.RegisterType<Func<string, IValidateCertificate>>((arg) => new ValidateCertificate(arg));
container.RegisterType<ICerthandler, CertificadoHandler>();
}
public class CertificadoHandler : ICertHandler
{
private readonly Func<string,IValidateCertificate> _createValidator;
public CertificadoHandler(Func<string,IValidateCertificate> func){
_createValidator= func;
}
public CredentialsData GetCredentialsData(X509Certificate cert)
{
return _createValidator("Foo").GetCredentialsData(cert);
}
}