I am trying to code a prototype project following Marcel's TempHire UOW example he sent me a few days ago but I am running up against a roadblock with my dynamically loaded XAP.
Currently I have a simple solution structure:
App.Core (main application shell project)
- App.Core.Services (my UOW/Repository project)
- App.Core.Model (my DF and EF entities)
App.Module1 (my dynamically loaded project)
- App.Module1.Services (my UOW/Repository project for Module1)
- App.Module1.Model (my DF and EF entities for Module1)
I am referencing a slightly newer version of Cocktail.SL.dll (v0.5) and a new Cocktail.Contrib.SL.dll I got from Marcel's sample. My app is SL5 as is my Cocktail.SL.dll but the Cocktail.Contrib.SL.dll is SL4. I don't have source to recompile the contrib library to SL5 but I assume it should reference fine in my SL5 app.
I am dynamically loading my Module1 XAP by calling Composition.AddXap, when it's completed I find its workspace and navigate to it.
[ImportMany(AllowRecomposition = true)]
public ObservableCollection<Lazy<IWorkspace, IModuleNameMetadata>> Workspaces { get; set; }
public IEnumerable<IResult> LoadModule(string name)
{
yield return Composition.AddXap(name + ".xap");
var ws = Workspaces
.Where(w => w.Metadata.Name.Equals(name + ".ViewModels.HomeViewModel"))
.Select(w => w.Value)
.FirstOrDefault();
if (ws != null)
NavigateTo(ws).ToSequentialResult().Execute();
}
[Export(typeof(IWorkspace)), ExportMetadata("Name", "App.Module1.ViewModels.HomeViewModel")]
public class HomeViewModel : Conductor<IScreen>, IDiscoverableViewModel, IHandle<EntityChangedMessage>, IWorkspace
From my main shell project I am able to import my UOW/Repository
[ImportingConstructor]
public ShellViewModel(IToolbarManager toolbar,
IShellRepositoryManager<IShellRepository> repositoryManager,
IAuthenticationService authenticationService)
Where I get into trouble is trying to import my Module1 UOW/Repository from App.Module1.ViewModels.HomeViewModel ctor.
[ImportingConstructor]
public HomeViewModel( IAppModule1RepositoryManager<IAppModule1Repository> repositoryManager,
IErrorHandler errorHandler,
IDialogManager dialogManager,
IToolbarManager toolbar)
{
This results in the following MEF error
System.ComponentModel.Composition Warning: 1 : The ComposablePartDefinition 'App.Module1.ViewModels.HomeViewModel' has been rejected. The composition remains unchanged. The changes were rejected because of the following error(s): The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.
1) No valid exports were found that match the constraint '((exportDefinition.ContractName == "App.Module1.Services.IAppModule1RepositoryManager(App.Module1.Services.IAppModule1Repository)") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "App.Module1.Services.IAppModule1RepositoryManager(App.Module1.Services.IAppModule1Repository)".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))', invalid exports may have been rejected.
My problem seems to be centered around my AppModule1RepositoryManager class. I get the above error when I base it off of ObjectManager.
[Export(typeof(IAppModule1RepositoryManager<IAppModule1Repository>))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class AppModule1RepositoryManager : ObjectManager<Guid, IAppModule1Repository>, IAppModule1RepositoryManager<IAppModule1Repository>
If I get rid of the ObjectManager base, like so
[Export(typeof(IAppModule1RepositoryManager<IAppModule1Repository>))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class AppModule1RepositoryManager : IAppModule1RepositoryManager<IAppModule1Repository>
My App.Module1 HomeViewModel ImportingConstructor works but the AppModule1RepositoryManager instance is basically empty without the ObjectManager.
I'm curious if I am missing something with the way I am dynamically loading my Module1 XAP that causes the ObjectManager to not import or is there a problem with having more than one imported ObjectManager?
Is there any sample code I could look at that touches on what I am trying to accomplish. Basically use Cocktail in a shell and dynamically loaded XAPs. Each XAP would be its own Caliburn workspace with many screens. Each screen would have its own UOW/Repository backed by each module's own EF/DevForce model.
Thanks... -Paul