2011-09-19 4 views
2

Je souhaite créer un dictionnaire d'objets d'usine pouvant être utilisés pour l'injection de dépendances.C# retourne un type sans avoir à le connaître

Par exemple, disons que j'ai une classe statique appelée ServiceLocator. Une application peut utiliser:

ITest test = ServiceLocator<ITest>.GetInstance() 

pour obtenir un objet implémentant l'interface ITest.

Pour mettre en œuvre ce j'ai créé une interface IFactory

public interface IFactory<T> 
{ 
    T GetInstance<T>(); 
} 

Ensuite, par exemple, une mise en œuvre concrète de ITest pourrait ressembler à ceci:

public class TestFactory : IFactory<ITest> 
{ 
    public ITest GetInstance<ITest> 
    { 
    return new (ITest)OneImplementationOfITest(); 
    } 

} 

ServiceLocator est alors définie comme ceci:

public static class ServiceLocator 
{ 
    private static Dictionary<string,object> m_Factories; 

    public static T GetInstance<T> 
    { 
     string type = typeof(T).ToString(); 

     return ((IFactory<T>)Factories[type]).GetInstance(); 
    } 
} 

Malheureusement, le T dans IFactory donne une compilation Erreur er:

« T doit être de type de référence afin de l'utiliser comme un paramètre T dans le type générique de la méthode ... »

Je peux penser à des façons de contourner ce, par exemple la définition IFactory au lieu de IFactory:

public interface IFactory 
{ 
    object GetInstance(); 
} 

mais l'utilisateur aurait besoin de jeter l'objet eux-mêmes:

ITest test = (ITest)ServiceLocator<ITest>.GetInstance(); 

qui est plutôt maladroit et pourrait conduire à des erreurs (par exemple pas coulée correctement)

serait encore mieux s'il y avait une façon d'écrire:

ITest test = ServiceLocator.GetInstance (« ITest ») mais n'ont pas compris comment faire.

Répondre

5

Essayez ceci:

public interface IFactory<T> 
    where T: class 
{ 
    T GetInstance<T>(); 
} 

Cela limite T être un type de référence. En passant, c'est l'un des nombreux disponibles generic type constraints.

+0

En fait, j'avais déjà essayé avec le même résultat. Cependant, votre message m'a donné une idée pour l'essayer sur la méthode GetInstance dans Service Locator et cela a fonctionné! –

Questions connexes