This project has moved. For the latest updates, please go here.

Problems with Import

Feb 29, 2012 at 9:52 AM
Edited Feb 29, 2012 at 10:04 AM

Hello

 

I am trying to do an application with Silverlight 4, Jounce 1 and MEF. For now, fake business objects help me to test the architecture.

I have a view “ImprimanteBidonView” who has a few TextBoxs, who are bounded to some properties in ImprimanteBidonViewModel.

 

Here is the code behind for the view, just the Jounce stuff:

 

    [ExportAsView(Global.CONFIG_IMPRIMANTEBIDON_VIEW)]
    [ExportViewToRegion(Global.CONFIG_IMPRIMANTEBIDON_VIEW, Global.MAIN_REGION)]
    public partial class ImprimanteBidonView : UserControl
    {
        public ImprimanteBidonView()
        {
            InitializeComponent();
        }


        [Export]
        public ViewModelRoute Binding
        {
            get { return ViewModelRoute.Create(Global.CONFIG_IMPRIMANTEBIDON_VIEWMODEL, Global.CONFIG_IMPRIMANTEBIDON_VIEW); }
        }
    }

 

 

In the viewModel, I import parameters for the constructor of the viewModel:

 

    public class ImprimanteBidonViewModel : BaseViewModel
    {
        private readonly ILog _logger;

        [ImportingConstructor]
        public ImprimanteBidonViewModel(IImprimanteBidon monImprimanteBidon, ILog logger)
        {
            NomServeurBleu = monImprimanteBidon.NomImprimante;
            UrlSb = monImprimanteBidon.UrlImprimante;
            Utilisateur = monImprimanteBidon.NomUtilisateur;
            SourceDonnees = monImprimanteBidon.ProvenanceDonnees;
            _logger = logger;
        }


 

The class ImprimanteBidon who implements IImprimanteBidon imports its parameters too:

    [Export(typeof(IImprimanteBidon))]
    public class ImprimanteBidon : IImprimanteBidon
    {
        private IDonneesImprBid _connecteurDonnees;
        private readonly ILog _logger;
 
 
        [ImportingConstructor]
        public ImprimanteBidon(IDonneesImprBid connecteurDonnees, ILog logger)
        {
 
            _connecteurDonnees = connecteurDonnees;
            _logger = logger;
            _nomImprimante = connecteurDonnees.NomImprimante;
            _urlImprimante = connecteurDonnees.UrlImprimante;
            _nomUtilisateur = connecteurDonnees.NomUtilisateur;
            _provenanceDonnees = connecteurDonnees.ProvenanceDonnees;
            _logger.Log("Constructeur Imprimante");
        }

IDonneesImprBid is implemented by the class DonneesImprXml (who imports nothing):
 [Export(typeof(IDonneesImprBid))] public class DonneesImprXml : IDonneesImprBid
ILog is implemented by the class FileLogger (who imports nothing):
 [Export(typeof(ILog))] public class FileLogger : ILog

It compiles but does not work. I get this error message: http://screencast.com/t/RGpxQ5QdslF


Now, if I delete one of the parameters of the view model constructor, like this:
        [ImportingConstructor]
        public ImprimanteBidonViewModel(IImprimanteBidon monImprimanteBidon)
        {
            NomServeurBleu = monImprimanteBidon.NomImprimante;
            UrlSb = monImprimanteBidon.UrlImprimante;
            Utilisateur = monImprimanteBidon.NomUtilisateur;
            SourceDonnees = monImprimanteBidon.ProvenanceDonnees;
            //_logger = logger;
        }
it works.

(to be followed below)
Feb 29, 2012 at 10:03 AM
Edited Feb 29, 2012 at 10:04 AM
The thing I can't do is 
 
[ImportingConstructor]   
public ImprimanteBidonViewModel(IImprimanteBidon monImprimanteBidon, ILog logger) 

I don't know why.

By the way, if I write
[Import]
IImprimanteBidon monImprimanteBidon {get; set}
 
        public ImprimanteBidonViewModel()
       {
           NomServeurBleu = monImprimanteBidon.NomImprimante;
           UrlSb = monImprimanteBidon.UrlImprimante;
           Utilisateur = monImprimanteBidon.NomUtilisateur;
           SourceDonnees = monImprimanteBidon.ProvenanceDonnees;
            //_logger = logger;
       }

 

so trying to import the object, but not in the constructor, it does not work. All others compositions are ok, but monImprimanteBidon has a null value.

 

I tried a lot of things but I can't get it working. I would be very grateful for your help, thank you.

 

Richard

Mar 1, 2012 at 3:01 PM
Edited Mar 1, 2012 at 3:23 PM

Hi,

Try making your importing property public and imlement  IPartImportsSatisfiedNotification as follows

 

    public class ImprimanteBidonViewModel: IPartImportsSatisfiedNotification
    {
        [Import]
        public IImprimanteBidon monImprimanteBidon {get; set}

        ...

        public void OnImportsSatisfied()
        {
            if(monImprimanteBidon != null)
            {
                SourceDonnees = monImprimanteBidon.ProvenanceDonnees;
            }
        }
    }  

If you need to reach the property in constructor then you need to use importing constructor.

 

Coordinator
Mar 1, 2012 at 3:23 PM

Thanks for helping with this - been busy at the summit this week. Let me know if you continue to have issues after implementing the suggestion above.

Mar 1, 2012 at 4:15 PM

Thanks for your help, e066377, and thank for your answer, Jeremy. Following the suggestion I wrote:

    [ExportAsViewModel(Global.CONFIG_IMPRIMANTEBIDON_VIEWMODEL)]
    public class ImprimanteBidonViewModel : BaseViewModelIPartImportsSatisfiedNotification
    {
        private readonly ILog _logger;
 
        [Import]
        public IImprimanteBidon monImprimanteBidon { getset; }
 
        [ImportingConstructor]
        //public ImprimanteBidonViewModel(IImprimanteBidon monImprimanteBidon, ILog logger)
        public ImprimanteBidonViewModel(ILog logger)
        {
  
            _logger = logger;
        }
 
        public void OnImportsSatisfied()
        {
            if (monImprimanteBidon == nullreturn;
            NomImprimanteBidon = monImprimanteBidon.NomImprimante;
            UrlSb = monImprimanteBidon.UrlImprimante;
            Utilisateur = monImprimanteBidon.NomUtilisateur;
            SourceDonnees = monImprimanteBidon.ProvenanceDonnees;
        }

It works!

Thanks a lot.

Richard