Je viens de commencer à utiliser MEF et j'ai rencontré un problème au début.MEF 'L'exportation n'est pas affectable au type' erreur
J'ai une interface appelée DataService:
namespace DataAccess
{
interface IDataService
{
string Name { get; }
string Description { get;}
List<String> GetPeople();
}
}
Il y a 2 implémentations de cette interface, un pour SQL Server et un pour Oracle. Ci-dessous l'implémentation Oracle, l'implémentation de SQL Server est exactement la même.
namespace DataAccess
{
[Export(typeof(IDataService))]
[ExportMetadata("Name","Oracle")]
[ExportMetadata("Description","Oracle Data Service")]
public class Oracle : IDataService
{
#region IDataService Members
public string Name
{
get { return "Oracle"; }
}
public string Description
{
get { return "Provides data access to Oracle database"; }
}
public List<string> GetPeople()
{
return new List<String>() { "Oracle boo", "Oracle boo1" };
}
#endregion
}
}
Les propriétés de nom et de description sont maintenant défunte comme je l'ai remplacé ces métadonnées. Comme vous pouvez le voir, ce sont des objets très simples, je voulais m'assurer que je pourrais le faire fonctionner avant que je commence à travailler dur.
C'est le code que je utilise pour découvrir les assemblées:
private static CompositionContainer _container;
private const string ASSEMBLY_PATTERN = "*.dll";
private AggregateCatalog _catalog;
[ImportMany]
IEnumerable<DataAccess.IDataService> services { get; set; }
private void button3_Click(object sender, EventArgs e)
{
_catalog = new AggregateCatalog(
new DirectoryCatalog(txtLibPath.Text, ASSEMBLY_PATTERN),
new AssemblyCatalog(Assembly.GetExecutingAssembly()));
_container = new CompositionContainer(_catalog);
_container.ComposeParts(this);
MessageBox.Show(services.Count().ToString());
}
Ceci est l'erreur qui est produite:
La composition produit une seule erreur de composition. La cause première est fournie ci-dessous. Consultez la propriété CompositionException.Errors pour plus d'informations.
1) L'exportation 'DataAccess.Oracle (ContractName = "DataAccess.IDataService")' n'est pas assignable pour taper 'DataAccess.IDataService'. Résultant de: Impossible d'initialiser 'MEFTest.Form1.services (ContractName = "DataAccess.IDataService")' sur la partie 'MEFTest.Form1'. Element: MEFTest.Form1.services (ContractName = « DataAccess.IDataService ») -> MEFTest.Form1
Il ne semble pas avoir de sens qu'il ne peut pas attribuer à l'interface qu'il a été conçu pour !
Une fois ce problème résolu, ma question suivante est de savoir comment choisir un et d'obtenir une instance de celui-ci ...
Vous aviez raison Daniel, j'avais recompilé IDataService pour les projets contenant les plugins SQLServer et Oracle, mais référençait une ancienne version dans l'application principale. J'ai déplacé l'IDataService dans un projet de bibliothèque de classes séparé et référencé cela à partir des trois projets et tout fonctionne parfaitement. Merci beaucoup. – hermiod
C'est un problème assez fastidieux. Il ne suffit pas de vérifier uniquement votre projet exe mais aussi les projets de tous les assemblages satellites qu'il charge. Dans mon cas exe chargé des projets de plus de 50 autres assemblées de satellites et j'ai eu du mal à suivre, ce qui provoque ce chargement en double. Si ce n'est pas un indice brillant de Daniel, je ne sais pas combien de temps je pourrais y consacrer. –