J'ai un peu de mal avec certains moulages que je n'arrive pas à résoudre.Casting object to generic T
J'ai cette interface et les implémentations suivantes:
public interface IConfigureServiceOnServer
{
void Configure(Service service);
}
public sealed class ServiceConfigurator : IConfigureServiceOnServer
{
...
}
je charge ces types lors de l'exécution en utilisant la méthode suivante un dictionnaire (qui contient les noms d'assemblage et de type):
public static T Resolve<T>(string type, params object[] values) where T : class
{
var split = refs[type].Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
var assembly = Assembly.LoadFrom(split[0] + ".dll");
var instance = assembly.CreateInstance(
split[1], // the name of the Type to instantiate
true,
BindingFlags.CreateInstance,
null,
values, // the params to use in the constructor
null,
null);
T ret = (T)instance; //also tried with 'instance as T'
return ret;
}
je reçois une exception coulée invalide lors de l'appel comme celui-ci
Resolver.Resolve<IConfigureServiceOnServer>("serviceconfiguration", "");
I c An't tout à fait comprendre pourquoi je reçois cette exception parce que le même code fonctionne pour la prochaine interface et sa mise en œuvre:
public interface IServiceManager
{
void Create();
void Configure();
}
public sealed class Service : IServiceManager
{
...
}
Toutes les idées pourquoi le même code fonctionne pour le 2ème exemple et non pour la première?
Merci d'avance.
EDIT:
Quand je suis débogage et j'arrêter l'exécution juste avant le retour dans la méthode Resolve je peux utiliser la fenêtre immédiate - i tester la distribution et il fonctionne.
EDIT2: Voici le message d'exception:
Unable to cast object of type 'Codegarten.Controller.Configuration.Service.ServiceConfigurator' to type 'Codegarten.Controller.Configuration.IConfigureServiceOnServer '.
EDIT3: Un peu plus d'info - Quelqu'un a suggéré le type chargé à l'aide de réflexion pourrait être mal si je l'ai fait un peu plus de débogage. Je vérifié pour voir si le type chargé en œuvre l'interface souhaitée en utilisant la fenêtre immédiate en studio visuel:
>instance.GetType().GetInterfaces()
{System.Type[1]}
[0]: {Name = "IConfigureServiceOnServer" FullName = "Codegarten.Controller.Configuration.IConfigureServiceOnServer"}
SOLUTION
Ok, le problème était dû à la méthode de Assembly.LoadFrom, qui a chargé l'ensemble dans un contexte différent de celui des applications. J'ai résolu ce problème en utilisant Assembly.Load à la place. J'ai résolu ce problème en utilisant Assembly.Load à la place.
Une raison pour laquelle vous ne pouvez pas utiliser un conteneur IoC? –
Au moment où vous obtenez l'exception, vous pouvez afficher le type de T et le type d'instance dans le débogueur. –
@Mattias: Le conteneur IoC n'est pas une option car ils offrent beaucoup plus que ce dont j'ai besoin. Je peux simplement charger les types en utilisant l'activateur @Chris: Bien sûr, je vais éditer le premier message avec le message d'exception. – Alka