How to Export from a Base Class without creating another instance?

Jan 10, 2012 at 1:33 PM

I'm developing an application based on Prism with Mef.
In my application i've created two classes, ShellViewModelBase and ShellViewModel, just like this:

    [PartCreationPolicy(CreationPolicy.Shared)]
    [Export(typeof(IShellViewModel))]
    public class ShellViewModelBase : ViewModelBaseIShellViewModel

    public class ShellViewModel : ShellViewModelBase
    {
        public ShellViewModel()
        {
            CompositionInitializer.SatisfyImports(this);
        }
    }

As the ShellViewModel, calls CompositionInitializer.SatisfyImports(this) i can't have more than one Export.
So, that's why i've created a base, ShellViewModelBase, to be able to export anything i want.
But when a part imports a IShellViewModel, an new instance of ShellViewModelBase is created. Here is how i'm importing:

        [Import(typeof(IShellViewModel), RequiredCreationPolicy = CreationPolicy.Shared)]
        public IShellViewModel ShellViewModel { getset; }


I don't want to create another instance, i would like to use the instance of ShellViewModel to be used instead.
I've tried to use Container.ComposeExportedValue just like this, in the Bootstrapper class:

Container.ComposeExportedValue<IShellViewModel>((Shell as Shell).shellViewModel);

But didn't work yet. An instance of the base class is still created.
Is there anything that i can do?

Thanks

Coordinator
Jan 10, 2012 at 5:40 PM

Hi,

Based on your code –snippet, SatisfyImports would do nothing, since ShellViewModel has no imports. I am unclear as to what it is you are trying to accomplish. Could you provide a little more detail, so we could help.

Thanks

-alok

From: lommez

I'm developing an application based on Prism with Mef.
In my application i've created two classes, ShellViewModelBase and ShellViewModel, just like this:

    [PartCreationPolicy(CreationPolicy.Shared)]
    [Export(typeof(IShellViewModel))]
    public class ShellViewModelBase : ViewModelBase, IShellViewModel
    public class ShellViewModel : ShellViewModelBase
    {

        public ShellViewModel()
        {
            CompositionInitializer.SatisfyImports(this);
        }

    }
 
 
 

As the ShellViewModel, calls CompositionInitializer.SatisfyImports(this) i can't have more than one Export.
So, that's why i've created a base, ShellViewModelBase, to be able to export anything i want.
But when a part imports a IShellViewModel, an new instance of ShellViewModelBase is created. Here is how i'm importing:

        [Import(typeof(IShellViewModel), RequiredCreationPolicy = CreationPolicy.Shared)]
        public IShellViewModel ShellViewModel { get; set; }


I don't want to create another instance, i would like to use the instance of ShellViewModel to be used instead.
I've tried to use Container.ComposeExportedValue just like this, in the Bootstrapper class:

Container.ComposeExportedValue<IShellViewModel>((Shell as Shell).shellViewModel);

But didn't work yet. An instance of the base class is still created.
Is there anything that i can do?


Jan 11, 2012 at 1:02 PM

Hi Alok,

Sorry to not be so clear.

In the class ShellViewModel i've many [Import], but i doesn't post them here on the code snippet. But i need to call the CompositionInitializer.SatisfyImports() to satisfy them.

I've created the base class ShellViewModelBase to allow to have [Export] without raising an exception when satisfying the imports, because i can't have more than one [Export], since i'm already exporting the Shell class.

But when my application statisfy the imports in another plugin module, an instance of ShellViewModelBase is created. And i dont want to create that instance. Instead of that, i want to use the instance of the ShellViewModel. So i've tried to use the ComposeExportedValue, but didnt work too. An instance of the ShewViewModelBase class is still being created.

Is there someway, when a import of the type IShellViewModel needs to be satisfied, to use the instance of ShewViewModel and not the creating a instance of ShewllViewModelBase class?

Here is a more complete code snippet of my application

The Shell class:

	[Export]
	public partial class Shell : UserControl
	{
		public ShellViewModel shellViewModel;
 
		[ImportingConstructor]
		public Shell(IModuleManager moduleManager, IRegionManager regionManager, IEventAggregator eventAggregator)
		{
			InitializeComponent();
			shellViewModel = new ShellViewModel(moduleManager, regionManager, eventAggregator);
			DataContext = shellViewModel;
		}
	}

The ShewlViewModelBase class:

    [PartCreationPolicy(CreationPolicy.Shared)]
    [Export(typeof(IShellViewModel))]
    public class ShellViewModelBase : ViewModelBaseIShellViewModel
    {
        public ShellViewModelBase()
        {
 
        }
 
        #region IShellViewModel Members
        public void ShowSomething()
        {
            MessageBox.Show("Showing something...");
        }
 
        public const string IsBusyPropertyName = "IsBusy";
        private bool _isBusy = false;
        public bool IsBusy
        {
            get { return _isBusy; }
            set
            {
                if (_isBusy == value)
                {
                    return;
                }
                _isBusy = value;
                RaisePropertyChanged(IsBusyPropertyName);
            }
        }
        #endregion
    }

 

The ShewViewModel class:

    public class ShellViewModel : ShellViewModelBase
    {
        private IEventAggregator _eventAggregator;
        private IModuleManager _moduleManager;
        private IRegionManager _regionManager;
 
        [Import(typeof(IDataService), RequiredCreationPolicy = CreationPolicy.Shared)]
        public IDataService _DataService { getset; }
 
        public ShellViewModel(IModuleManager moduleManager, IRegionManager regionManager, IEventAggregator eventAggregator)
        {
            CompositionInitializer.SatisfyImports(this);
 
            this._moduleManager = moduleManager;
            this._regionManager = regionManager;
            this._eventAggregator = eventAggregator;
        }

 

The plugin module that imports the IShellViewModel:

    public class Module1VM : TabItemViewModelINotifyPropertyChanged
    {  
        [Import(typeof(IShellViewModel))]
        public IShellViewModel ShellViewModel { getset; } 
 
        public Module1VM(IRegionManager regionManager, IEventAggregator eventAggregator)
        {
            CompositionInitializer.SatisfyImports(this);
 
            this._regionManager = regionManager;
            this._eventAggregator = eventAggregator;
        }

 

In the bootstrapper class i'm trying to compose the exported value:

Container.ComposeExportedValue<IShellViewModel>((Shell as Shell).shellViewModel);

 

Thanks Alok!

Best Regards,

Marcos Lommez