Reputation: 429
I always developed application in MVVM in one project and separate Model, View, ViewModel wth folders. Looking in different questions and different books I learnt that separate them in different projects will be better for different reasons so I was trying to develop a simple project to see how it works.
Firstly I created a single project with different folders, and i start the application and it works good. This how is the structured the "single project" I have omitted the Model folder.
After I created multiple project composed of these 3 projects:
-MVVM
-MVVM.Views
-MVVM.ViewModels
This how i structured the "multiple project"
I set the MVVM.Views,MVVM.ViewModels output type to Dll and not to .exe, i added the projects(MVVM.Views,MVVM.ViewModels) references in MVVM.
But when i lunch the application i get an error
An unhandled exception of type 'System.Exception' occurred in WindowsBase.dll Informations: Could not locate any instances of contract MVVM.ViewModels.IShell.
I'm using also Caliburn.Micro 2.0.2 for bootstrapp and this is the MefBootstrapper:
public class MefBootstrapper : BootstrapperBase
{
private CompositionContainer container;
public MefBootstrapper()
{
Initialize();
}
protected override void Configure()
{
var catalog = new AggregateCatalog(
AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()
);
container = new CompositionContainer(catalog);
var batch = new CompositionBatch();
batch.AddExportedValue<IWindowManager>(new WindowManager());
batch.AddExportedValue<IEventAggregator>(new EventAggregator());
batch.AddExportedValue(container);
container.Compose(batch);
}
protected override object GetInstance(Type serviceType, string key)
{
string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(serviceType) : key;
var exports = container.GetExportedValues<object>(contract);
if (exports.Count() > 0)
return exports.First();
throw new Exception(string.Format("Could not locate any instances of contract {0}.", contract));
}
protected override IEnumerable<object> GetAllInstances(Type serviceType)
{
return container.GetExportedValues<object>(AttributedModelServices.GetContractName(serviceType));
}
protected override void BuildUp(object instance)
{
container.SatisfyImportsOnce(instance);
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
DisplayRootViewFor<IShell>();
}
}
This is ViewModel code:
namespace MVVM.ViewModels
{
public interface IShell { }
[Export(typeof(IShell))]
public class MainViewModel : PropertyChangedBase, IShell
{
}
}
I want to understand where i wrong? I missed one step? Thanks for support
Upvotes: 1
Views: 3743
Reputation: 429
I post the answer just in case someone will have my same problems. After reading a lot of posts and different stuff I've found the error. I forgot to load the assemblies into the application. And this is really easy just change the Configure()
void here the code:
protected override void Configure()
{
string pluginPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "");
if (!Directory.Exists(pluginPath))
Directory.CreateDirectory(pluginPath);
var fi = new DirectoryInfo(pluginPath).GetFiles("*.dll");
AssemblySource.Instance.AddRange(fi.Select(fileInfo => Assembly.LoadFrom(fileInfo.FullName)));
var catalog = new AggregateCatalog(
AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()
);
container = new CompositionContainer(catalog);
var batch = new CompositionBatch();
batch.AddExportedValue<IWindowManager>(new WindowManager());
batch.AddExportedValue<IEventAggregator>(new EventAggregator());
batch.AddExportedValue(container);
container.Compose(batch);
}
Upvotes: 2