Print Page | Close Window

IEventAggregator

Printed From: IdeaBlade
Category: Cocktail
Forum Name: Community Forum
Forum Discription: A professional application framework using Caliburn.Micro and DevForce
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=3437
Printed Date: 14-May-2025 at 10:33pm


Topic: IEventAggregator
Posted By: murray.bryant
Subject: IEventAggregator
Date Posted: 11-May-2012 at 4:13am
Hi 

I am trying to move to Cocktail from DAF. I have almost everything working apart from not being able to import IEventAgregator.

1) No valid exports were found that match the constraint '((exportDefinition.ContractName == "Caliburn.Micro.IEventAggregator") 

I am at a loss as to why it is not being exported.

I have included my Bootstrapper code. Hopefully someone can see what I am doing wrong and needs to be changed. It all worked in the old DAF.

Thanks

 public class WpfBootstrapper : FrameworkBootstrapper<IShell>
    {


        private CompositionContainer _container;

        public WpfBootstrapper()
        {
            // Uncomment to enable Caliburn Micro logging
            // LogManager.GetLog = (Type t) => Torpedo.Geo.Shared.Helper.CaliburnDebugLog.GetInstanceForType(t);
        }


      

        protected override void PrepareCompositionContainer(CompositionBatch batch)
        {
            base.PrepareCompositionContainer(batch);


            // batch.AddExportedValue<IWindowManager>(new WindowManager());
        

            _container = new CompositionContainer(new AggregateCatalog(
                AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()
                ));
            
            batch.AddExportedValue<IEntityManagerProvider<TorpedoEntities>>(new EntityManagerProvider<TorpedoEntities>());
          
          

            batch.AddExportedValue<IAuthenticationService>(new AuthenticationService());

            batch.AddExportedValue<Func<IMessageBox>>(() => _container.GetExportedValue<IMessageBox>());

            batch.AddExportedValue<Func<ILocationViewModel>>(() => _container.GetExportedValue<ILocationViewModel>());
            batch.AddExportedValue<Func<IAssayBatchViewModel>>(() => _container.GetExportedValue<IAssayBatchViewModel>());
            batch.AddExportedValue<Func<IImportToDataViewViewModel>>(() => _container.GetExportedValue<IImportToDataViewViewModel>());
            batch.AddExportedValue<Func<IImportToObjectsViewModel>>(() => _container.GetExportedValue<IImportToObjectsViewModel>());

            _container.Compose(batch);
           
        }

        protected override IEnumerable<Assembly> SelectAssemblies()
        {
            return new[] { 
                 Assembly.GetExecutingAssembly(),
                 
                 //Assembly.LoadFrom("Torpedo.Geo.WPF.Mapping.dll"),
                 Assembly.LoadFrom("Torpedo.Geo.WPF.Viewer.dll"),
                 Assembly.LoadFrom("Torpedo.Geo.WPF.LocationDetail.dll"),
                 Assembly.LoadFrom("Torpedo.Geo.WPF.Assay.dll"),
                 Assembly.LoadFrom("Torpedo.Geo.WPF.Admin.dll"),
                 Assembly.LoadFrom("Torpedo.Geo.WPF.Import.dll"),
                 Assembly.LoadFrom("Torpedo.Geo.Shared.dll")
            };
        }

        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)
        {
            base.BuildUp(instance);
            _container.SatisfyImportsOnce(instance);
         
        }




Replies:
Posted By: murray.bryant
Date Posted: 11-May-2012 at 6:27am
I got it to work.

My bootstrapper is now just this:


        private CompositionContainer _container;

        public WpfBootstrapper()
        {
            // Uncomment to enable Caliburn Micro logging
            // LogManager.GetLog = (Type t) => Torpedo.Geo.Shared.Helper.CaliburnDebugLog.GetInstanceForType(t);
        }


      

        protected override void PrepareCompositionContainer(CompositionBatch batch)
        {
            base.PrepareCompositionContainer(batch);


           //  batch.AddExportedValue<IWindowManager>(new Torpedo.Geo.WPF.TorpedoWindowManager());
        

            _container = new CompositionContainer(new AggregateCatalog(
                AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()
                ));
            
          //  batch.AddExportedValue<IEntityManagerProvider<TorpedoEntities>>(new EntityManagerProvider<TorpedoEntities>());

           

            batch.AddExportedValue<IAuthenticationService>(new AuthenticationService());

            batch.AddExportedValue<Func<IMessageBox>>(() => _container.GetExportedValue<IMessageBox>());

            batch.AddExportedValue<Func<ILocationViewModel>>(() => _container.GetExportedValue<ILocationViewModel>());
            batch.AddExportedValue<Func<IAssayBatchViewModel>>(() => _container.GetExportedValue<IAssayBatchViewModel>());
            batch.AddExportedValue<Func<IImportToDataViewViewModel>>(() => _container.GetExportedValue<IImportToDataViewViewModel>());
            batch.AddExportedValue<Func<IImportToObjectsViewModel>>(() => _container.GetExportedValue<IImportToObjectsViewModel>());

            _container.Compose(batch);
           
        }


The rest is not needed anymore





Posted By: mgood
Date Posted: 11-May-2012 at 1:16pm
That still doesn't look right at all. Why are you creating your own container? Cocktail creates the container for you. Please see the bootstrapper chapter in the documentation:
 
http://drc.ideablade.com/xwiki/bin/view/Documentation/cocktail-application-bootstrapper - http://drc.ideablade.com/xwiki/bin/view/Documentation/cocktail-application-bootstrapper


Posted By: murray.bryant
Date Posted: 11-May-2012 at 3:57pm
Hi Marcel

I am doing this because I need to add  batch.AddExportedValue<Func<ILocationViewModel>> functions and the export of ILocationViewModel is not available  at this point in the container because my solution is split across multiple projects.

It took ages to get this to work, through ignorance,  black magic and luck. One of the reasons I went through the pain of switching to Cocktail is that you are making an effort to document it. Which is great!

Do you know a better way to add the Func <T> into the container?  I did look at the documentation but I can't see anything about this.

Thanks

Murray



Posted By: mgood
Date Posted: 11-May-2012 at 4:08pm
batch.AddExportedValue<Func<ILocationViewModel>>(() => Composition.GetInstance<ILocationViewModel>());


Posted By: mgood
Date Posted: 11-May-2012 at 4:12pm
Hit post a little fast. I'm not quite understanding your issue. Is the ILocationViewModel in a different XAP that gets dynamically loaded?


Posted By: murray.bryant
Date Posted: 11-May-2012 at 4:16pm
This is a WPF app initially we started in silverlight which might be why we had it set like that. But yes the exports are in different dll's

Your suggestion worked though.

My bootstrapper is now much cleaner:

 protected override void PrepareCompositionContainer(CompositionBatch batch)
        {
            base.PrepareCompositionContainer(batch);


            batch.AddExportedValue<IAuthenticationService>(new AuthenticationService());

            batch.AddExportedValue<Func<IMessageBox>>(() => Composition.GetInstance<IMessageBox>());
            batch.AddExportedValue<Func<ILocationViewModel>>(() => Composition.GetInstance<ILocationViewModel>());
            batch.AddExportedValue<Func<IAssayBatchViewModel>>(() => Composition.GetInstance<IAssayBatchViewModel>());
            batch.AddExportedValue<Func<IImportToDataViewViewModel>>(() => Composition.GetInstance<IImportToDataViewViewModel>());
            batch.AddExportedValue<Func<IImportToObjectsViewModel>>(() => Composition.GetInstance<IImportToObjectsViewModel>());
      
           
        }

        


Posted By: mgood
Date Posted: 11-May-2012 at 5:07pm
Yeah, you shouldn't have any issues with this even in Silverlight unless you dynamically load XAPs at runtime, then obviously the exports won't be available until the XAP file got loaded. Exports can be spread over multiple dlls, as long as they are discovered. The default container created by Cocktail gets initialized with the PartsCatalog from DevForce, which contains all your exports unless you mess with the DevForce discovery. DevForce does exclude some assemblies based on their names. For example every assembly starting with IdeaBlade. There are a bunch of others, like third-party vendor assemblies etc. You can get an issue if you accidentally name an assembly such that it happens to match one of the exclusion rules.
 
http://drc.ideablade.com/xwiki/bin/view/Documentation/discovery - http://drc.ideablade.com/xwiki/bin/view/Documentation/discovery
 
In summary, you shouldn't need this func exports. The container should have all exports in it when the bootstrapper is done.



Print Page | Close Window