New Posts New Posts RSS Feed: Custom ConnectionOptions?
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Custom ConnectionOptions?

 Post Reply Post Reply Page  12>
Author
Siyfion View Drop Down
Groupie
Groupie
Avatar

Joined: 22-Mar-2012
Location: Bristol, UK
Posts: 47
Post Options Post Options   Quote Siyfion Quote  Post ReplyReply Direct Link To This Post Topic: Custom ConnectionOptions?
    Posted: 22-Mar-2012 at 6:12am
This may sound silly, but after creating a custom implementation of IConnectionOptionsResolver, how do I actually use it!? In particular, if I am using a single shared EntityManagerProvider throughout the application?
Back to Top
mgood View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
Post Options Post Options   Quote mgood Quote  Post ReplyReply Direct Link To This Post Posted: 22-Mar-2012 at 6:26am
You use it by specifiying the name of the ConnectionOptions you want your EntityManagerProvider to use through the "With" method. Note that the With method clones the EMP and configures the clone with the new ConnectionOptions. If you use a single shared EntityManagerProvider, I assume you are currently instantiating it in the PrepareCompositionContainer method in your bootstrapper and add it to the CompositionBatch. In that case, you would do the following:
 
        protected override void PrepareCompositionContainer(CompositionBatch batch)
        {
            base.PrepareCompositionContainer(batch);
 
            batch.AddExportedValue<IEntityManagerProvider<yourentitymanagertype>>(
                new EntityManagerProvider<yourentitymanagertype>().With("yourconnectionoptionname"));
        }


Edited by mgood - 22-Mar-2012 at 6:28am
Back to Top
Siyfion View Drop Down
Groupie
Groupie
Avatar

Joined: 22-Mar-2012
Location: Bristol, UK
Posts: 47
Post Options Post Options   Quote Siyfion Quote  Post ReplyReply Direct Link To This Post Posted: 22-Mar-2012 at 6:39am

Perhaps I'm getting a bit confused; is the name I am specifying the name of the class, or the name contained within the returned ConnectionOptions?

If it's the name of the class, I've tried that and put a breakpoint in GetConnectionOptions, but it never seemed to be hit, at what point would it call this?

Back to Top
Siyfion View Drop Down
Groupie
Groupie
Avatar

Joined: 22-Mar-2012
Location: Bristol, UK
Posts: 47
Post Options Post Options   Quote Siyfion Quote  Post ReplyReply Direct Link To This Post Posted: 22-Mar-2012 at 6:41am
Ah ignore me, I wasn't using the EntityManagerProvider anywhere, as soon as I did, it hit the breakpoint. Thanks!
Back to Top
Siyfion View Drop Down
Groupie
Groupie
Avatar

Joined: 22-Mar-2012
Location: Bristol, UK
Posts: 47
Post Options Post Options   Quote Siyfion Quote  Post ReplyReply Direct Link To This Post Posted: 22-Mar-2012 at 6:47am

Ok, I've managed to get a bit further... 

Dare I ask how one goes about specifying login credentials when connecting via the EntityManagerProvider?

Back to Top
Siyfion View Drop Down
Groupie
Groupie
Avatar

Joined: 22-Mar-2012
Location: Bristol, UK
Posts: 47
Post Options Post Options   Quote Siyfion Quote  Post ReplyReply Direct Link To This Post Posted: 22-Mar-2012 at 7:42am

Any idea what would produce this error:

The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

1) Unable to start EntityServer_Cloud.svc service: The service '/EntityServer_Cloud.svc' cannot be activated due to an exception during compilation. The exception message is: CompositionContext: '-IbDefault-' - Probed for non-default 'IEntityLoginManager' and found more than one implementation - (Error):
PG.LLL.WebService.LoginManager, WebApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
PG.WebService.LoginManager, WebService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.

Resulting in: Unable to start EntityServer_Cloud.svc service: The service '/EntityServer_Cloud.svc' cannot be activated due to an exception during compilation. The exception message is: CompositionContext: '-IbDefault-' - Probed for non-default 'IEntityLoginManager' and found more than one implementation - (Error):
PG.LLL.WebService.LoginManager, WebApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
PG.WebService.LoginManager, WebService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.

Resulting in: An exception occurred while trying to create an instance of type 'PG.LLLAdmin.ViewModels.ShellViewModel'.

Resulting in: Cannot activate part 'PG.LLLAdmin.ViewModels.ShellViewModel'.
Element: PG.LLLAdmin.ViewModels.ShellViewModel --> PG.LLLAdmin.ViewModels.ShellViewModel --> AssemblyCatalog (Assembly="LLLAdmin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")

Resulting in: Cannot get export 'PG.LLLAdmin.ViewModels.ShellViewModel (ContractName="PG.LLLAdmin.ViewModels.IShell")' from part 'PG.LLLAdmin.ViewModels.ShellViewModel'.
Element: PG.LLLAdmin.ViewModels.ShellViewModel (ContractName="PG.LLLAdmin.ViewModels.IShell") --> PG.LLLAdmin.ViewModels.ShellViewModel --> AssemblyCatalog (Assembly="LLLAdmin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")

Back to Top
Siyfion View Drop Down
Groupie
Groupie
Avatar

Joined: 22-Mar-2012
Location: Bristol, UK
Posts: 47
Post Options Post Options   Quote Siyfion Quote  Post ReplyReply Direct Link To This Post Posted: 22-Mar-2012 at 10:22am
Ok, I've now managed to somehow dodge that last issue, although I'm still not entirely sure what caused it due to the rather cryptic error message. (FYI I only had one class that implemented the IEntityLoginManager interface, not two!)

Now I've got the application starting up, and (apparently) successfully logging into the entity server web service; I can even create a new entity using Manager.CreateEntity<User>(); and Manager.AddEntity(xx). However, as soon as I try to Save, or perform a query on data that's already in the database:

The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

1) Unable to login: Object reference not set to an instance of an object.

Resulting in: An exception occurred while trying to create an instance of type 'PG.LLLAdmin.ViewModels.ShellViewModel'.

Resulting in: Cannot activate part 'PG.LLLAdmin.ViewModels.ShellViewModel'.
Element: PG.LLLAdmin.ViewModels.ShellViewModel -->  PG.LLLAdmin.ViewModels.ShellViewModel -->  AssemblyCatalog (Assembly="LLLAdmin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")

Resulting in: Cannot get export 'PG.LLLAdmin.ViewModels.ShellViewModel (ContractName="PG.LLLAdmin.ViewModels.IShell")' from part 'PG.LLLAdmin.ViewModels.ShellViewModel'.
Element: PG.LLLAdmin.ViewModels.ShellViewModel (ContractName="PG.LLLAdmin.ViewModels.IShell") -->  PG.LLLAdmin.ViewModels.ShellViewModel -->  AssemblyCatalog (Assembly="LLLAdmin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")

Back to Top
mgood View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
Post Options Post Options   Quote mgood Quote  Post ReplyReply Direct Link To This Post Posted: 22-Mar-2012 at 4:31pm
Originally posted by Siyfion

Ok, I've managed to get a bit further... 

Dare I ask how one goes about specifying login credentials when connecting via the EntityManagerProvider?

 
Back to Top
mgood View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
Post Options Post Options   Quote mgood Quote  Post ReplyReply Direct Link To This Post Posted: 22-Mar-2012 at 4:38pm
Originally posted by Siyfion

Ok, I've now managed to somehow dodge that last issue, although I'm still not entirely sure what caused it due to the rather cryptic error message. (FYI I only had one class that implemented the IEntityLoginManager interface, not two!)

Now I've got the application starting up, and (apparently) successfully logging into the entity server web service; I can even create a new entity using Manager.CreateEntity<User>(); and Manager.AddEntity(xx). However, as soon as I try to Save, or perform a query on data that's already in the database:

The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

1) Unable to login: Object reference not set to an instance of an object.

Resulting in: An exception occurred while trying to create an instance of type 'PG.LLLAdmin.ViewModels.ShellViewModel'.

Resulting in: Cannot activate part 'PG.LLLAdmin.ViewModels.ShellViewModel'.
Element: PG.LLLAdmin.ViewModels.ShellViewModel -->  PG.LLLAdmin.ViewModels.ShellViewModel -->  AssemblyCatalog (Assembly="LLLAdmin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")

Resulting in: Cannot get export 'PG.LLLAdmin.ViewModels.ShellViewModel (ContractName="PG.LLLAdmin.ViewModels.IShell")' from part 'PG.LLLAdmin.ViewModels.ShellViewModel'.
Element: PG.LLLAdmin.ViewModels.ShellViewModel (ContractName="PG.LLLAdmin.ViewModels.IShell") -->  PG.LLLAdmin.ViewModels.ShellViewModel -->  AssemblyCatalog (Assembly="LLLAdmin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")

 
You are doing something in the ShellViewModel constructor that blows up, so the instance creation fails. Why it would create an instance of the ShellViewModel, though, when you try to save is confusing me. Given the name I assume this is your main ViewModel. If that's so it would get created before you run your first query.
 
I sense there's something upside down. From where did you run the query etc. How do you login (see my previous post)?
Back to Top
Siyfion View Drop Down
Groupie
Groupie
Avatar

Joined: 22-Mar-2012
Location: Bristol, UK
Posts: 47
Post Options Post Options   Quote Siyfion Quote  Post ReplyReply Direct Link To This Post Posted: 22-Mar-2012 at 4:42pm
It was crashing in another place, but to try it out I moved some code into my ShellViewModel constructor, so it now looks like this:

    [Export(typeof(IShell))]
    class ShellViewModel : Conductor<IScreen>, IShell
    {
        private readonly IAuthenticationService _authenticationService;

        [ImportingConstructor]
        public ShellViewModel(IAuthenticationService authenticationService)
        {
            _authenticationService = authenticationService;

            var loginCredential = new LoginCredential("Dev", null, null);
            _authenticationService.Login(loginCredential);

            var userRepository = IoC.Get<IUserRepository>();
            var owner = userRepository.CreateOwner();
            var saveResult = userRepository.SaveSync();

            ShowSheetCreation();
        }

        public void ShowSheetCreation()
        {
            var sheetCreation = IoC.Get<ISheetCreation>();
            ActivateItem(sheetCreation);
        }

        private string _title;
        public string Title
        {
            get { return _title; }
            set
            {
                if (_title == value) return;
                _title = value;
                NotifyOfPropertyChange(() => Title);
            }
        }

        public void SetTitle(string title)
        {
            if (!string.IsNullOrEmpty(title))
                Title = title;
        }
    }

And my AppBootstrapper:

        protected override void Configure()
        {
            _container =
                new CompositionContainer(
                    new AggregateCatalog(
                        AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()));

            var batch = new CompositionBatch();
            batch.AddExportedValue<IWindowManager>(new WindowManager());
            batch.AddExportedValue<IEventAggregator>(new EventAggregator());
            batch.AddExportedValue<IEntityManagerProvider<LabelLogicEntities>>(
                new EntityManagerProvider<LabelLogicEntities>().With(ConnectionOptions.Default.Name));
            batch.AddExportedValue<IAuthenticationService>(
                new AuthenticationService().With(ConnectionOptions.Default.Name));
            batch.AddExportedValue(_container);

            _container.Compose(batch);

            Application.ShutdownMode = ShutdownMode.OnExplicitShutdown;
        }
Back to Top
Siyfion View Drop Down
Groupie
Groupie
Avatar

Joined: 22-Mar-2012
Location: Bristol, UK
Posts: 47
Post Options Post Options   Quote Siyfion Quote  Post ReplyReply Direct Link To This Post Posted: 22-Mar-2012 at 5:04pm
Ok, yet again I've got it a step closer, however now I've got the error:

1) Call Connect() before doing a Login.

So I'm guessing that I manually need to call Connect() on the EntityManagerProvider.Manager?
Back to Top
Siyfion View Drop Down
Groupie
Groupie
Avatar

Joined: 22-Mar-2012
Location: Bristol, UK
Posts: 47
Post Options Post Options   Quote Siyfion Quote  Post ReplyReply Direct Link To This Post Posted: 23-Mar-2012 at 2:16am
I've changed my constructor to the following, but I'm still getting an exception thrown, when I try to perform either a Save() or a SaveAsync() on the user repository, which internally just call Manager.SaveChanges() or Manager.SaveChangesAsync(). 

        [ImportingConstructor]
        public ShellViewModel(IAuthenticationService authenticationService)
        {
            _authenticationService = authenticationService;

            var loginCredential = new LoginCredential("Dev", null, null);
            _authenticationService.Login(loginCredential);

            var entityManagerProvider = IoC.Get<IEntityManagerProvider<LabelLogicEntities>>();
            entityManagerProvider.Manager.Connect();

            var userRepository = IoC.Get<IUserRepository>();
            var owner = userRepository.CreateOwner();
            var saveResult = userRepository.SaveAsync(OnSuccess, OnFail);

            ShowSheetCreation();
        }

        private void OnFail(Exception exception)
        {
            throw exception;
        }

        private void OnSuccess()
        {
            throw new NotImplementedException();
        }

The OnFail throws the following:

Unable to login: Object reference not set to an instance of an object.
Back to Top
Siyfion View Drop Down
Groupie
Groupie
Avatar

Joined: 22-Mar-2012
Location: Bristol, UK
Posts: 47
Post Options Post Options   Quote Siyfion Quote  Post ReplyReply Direct Link To This Post Posted: 23-Mar-2012 at 2:33am
Here's the DevForce / Cocktail generated output:

0 : 23/03/2012 09:27:12 :  : Cocktail.Composition:WarnIfNotConfigured : WARNING: Composition has not been configured. Not all types may be available.
1 : 23/03/2012 09:27:13 :  : IdeaBlade.Core.Composition.PartsCatalog:LoadCatalog : MEF assembly probing started: 23/03/2012 09:27:13.  If this takes a long time, use IdeaBlade.Core.Composition.CompositionHost to specify/restrict which assemblies to probe.
2 : 23/03/2012 09:27:13 :  : IdeaBlade.Core.IdeaBladeConfig:Initialize : Initializing configuration ...
3 : 23/03/2012 09:27:13 :  : IdeaBlade.Core.Composition.PartsCatalog:LoadCatalog : MEF assembly probing started: 23/03/2012 09:27:13.  If this takes a long time, use IdeaBlade.Core.Composition.CompositionHost to specify/restrict which assemblies to probe.
4 : 23/03/2012 09:27:13 :  : IdeaBlade.Core.Composition.PartsCatalog:LoadCatalog : Assembly 'Cocktail, Version=0.4.0.494, Culture=neutral, PublicKeyToken=7d8c7326b555a04a' added to PartsCatalog
5 : 23/03/2012 09:27:13 :  : IdeaBlade.Core.Composition.PartsCatalog:LoadCatalog : Assembly 'LabelLogicLiveAdmin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' added to PartsCatalog
6 : 23/03/2012 09:27:13 :  : IdeaBlade.Core.Composition.PartsCatalog:LoadCatalog : MEF assembly probing completed: 23/03/2012 09:27:13
7 : 23/03/2012 09:27:13 :  : IdeaBlade.Core.Composition.CompositionHost:.ctor : Probe Assemblies: Caliburn.Micro, Version=1.3.1.0, Culture=neutral, PublicKeyToken=8e5891231f2ed21f :: Cocktail, Version=0.4.0.494, Culture=neutral, PublicKeyToken=7d8c7326b555a04a :: Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null :: DataModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null :: LabelLogicLiveAdmin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null  If this list is unnecessarily large, use CompositionHost.SearchPatterns to modify the search critieria for probed assemblies. If this list does not contain the assembly(ies) holding your a) domain model, b) custom interface implementations, and c) POCO/known types then your application may not work correctly. Ensure that these assemblies are available in the exe/bin folder, and if using CompositionHost.SearchPatterns that the patterns are set appropriately.
8 : 23/03/2012 09:27:13 :  : IdeaBlade.Core.IdeaBladeConfig+<>c__DisplayClass2:<Initialize>b__1 : IdeaBlade License: 'EnterpriseWinClient, Express', KeyDate: 15/04/2010, AllowedSessions: 10000. Found on Assembly: 'DataModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
9 : 23/03/2012 09:27:13 :  : IdeaBlade.Core.Configuration.ServerSettingsElement:ConstrainSettingsBasedOnLicenseCore : The configured SupportedClientApplicationType is WinClient
10 : 23/03/2012 09:27:13 :  : IdeaBlade.Core.Configuration.ServerSettingsElement:ConstrainSettingsBasedOnLicenseCore : Could not find a valid license to enable session-agnostic load balancing.
11 : 23/03/2012 09:27:14 :  : IdeaBlade.Core.Composition.CompositionHost:CheckMultiExport : CompositionContext: '-IbDefault-' - Probed for non-default 'ITraceLoggerProvider' and found 'Cocktail.TraceLoggerProvider'.
13 : 23/03/2012 09:27:14 :  : IdeaBlade.Core.TraceFns:CompleteTracingInitialization : IdeaBladeConfig resolution: File: C:\Development\Planglow_Test\Cocktail_Test\LabelLogicLive\LabelLogicLiveAdmin\bin\Debug\LabelLogicLiveAdmin.vshost.exe.Config - found
14 : 23/03/2012 09:27:14 :  : IdeaBlade.Core.TraceFns:CompleteTracingInitialization : IdeaBladeConfig resolution: Logging file: C:\Development\Planglow_Test\Cocktail_Test\LabelLogicLive\LabelLogicLiveAdmin\bin\Debug\DebugLog.xml
15 : 23/03/2012 09:27:14 :  : IdeaBlade.Core.TraceFns:CompleteTracingInitialization : Bound to .NET runtime version 4.0.30319.261
16 : 23/03/2012 09:27:14 :  : IdeaBlade.Core.TraceFns:CompleteTracingInitialization : DevForce version 6.1.6.0
17 : 23/03/2012 09:27:14 :  : IdeaBlade.Core.Composition.PartsCatalog:LoadCatalog : Assembly 'Cocktail, Version=0.4.0.494, Culture=neutral, PublicKeyToken=7d8c7326b555a04a' added to PartsCatalog
18 : 23/03/2012 09:27:14 :  : IdeaBlade.Core.Composition.PartsCatalog:LoadCatalog : Assembly 'LabelLogicLiveAdmin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' added to PartsCatalog
19 : 23/03/2012 09:27:14 :  : IdeaBlade.Core.Composition.PartsCatalog:LoadCatalog : MEF assembly probing completed: 23/03/2012 09:27:14
20 : 23/03/2012 09:27:14 :  : IdeaBlade.Core.Composition.CompositionHost:.ctor : Probe Assemblies: Caliburn.Micro, Version=1.3.1.0, Culture=neutral, PublicKeyToken=8e5891231f2ed21f :: Cocktail, Version=0.4.0.494, Culture=neutral, PublicKeyToken=7d8c7326b555a04a :: Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null :: DataModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null :: LabelLogicLiveAdmin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null  If this list is unnecessarily large, use CompositionHost.SearchPatterns to modify the search critieria for probed assemblies. If this list does not contain the assembly(ies) holding your a) domain model, b) custom interface implementations, and c) POCO/known types then your application may not work correctly. Ensure that these assemblies are available in the exe/bin folder, and if using CompositionHost.SearchPatterns that the patterns are set appropriately.
21 : 23/03/2012 09:27:14 :  : IdeaBlade.EntityModel.EntityServerProxy:GetInstance : Loaded IdeaBlade.EntityModel.RemoteEntityServerProxy
22 : 23/03/2012 09:27:14 :  : IdeaBlade.Core.Composition.CompositionHost:CheckSingleExport : CompositionContext: '-IbDefault-' - Probed for default 'IDataSourceKeyResolver' and found 'IdeaBlade.EntityModel.DefaultDataSourceKeyResolver'.
23 : 23/03/2012 09:27:14 :  : Cocktail.EntityManagerProvider`1:CreateEntityManager : Successfully created new instance of EntityManager: Planglow.DataModel.LabelLogicEntities with connection info: DesignTime, IsFake=False.
24 : 23/03/2012 09:27:14 :  : Cocktail.Composition:WarnIfNotConfigured : WARNING: Composition has not been configured. Not all types may be available.
25 : 23/03/2012 09:27:14 :  : Cocktail.Composition:WarnIfNotConfigured : WARNING: Composition has not been configured. Not all types may be available.
26 : 23/03/2012 09:27:15 :  : IdeaBlade.EntityModel.WcfProxy`1:CreateProxyCore : Trying programmatic configuration of EntityService
27 : 23/03/2012 09:27:15 :  : IdeaBlade.EntityModel.RemoteServiceFns:AddSerializationBehavior : Using DC serializer for EntityService
28 : 23/03/2012 09:27:15 :  : IdeaBlade.Core.Composition.CompositionHost:CheckSingleExport : CompositionContext: '-IbDefault-' - Probed for any 'ServiceProxyEvents' and found 'IdeaBlade.EntityModel.ServiceProxyEvents'.
29 : 23/03/2012 09:27:15 :  : IdeaBlade.EntityModel.WcfProxy`1:CreateProxyCore : Created proxy to EntityService using Uri http://127.0.0.1:9009/EntityService.svc
The thread '<No Name>' (0x17d4) has exited with code 0 (0x0).
30 : 23/03/2012 09:27:18 :  : IdeaBlade.EntityModel.WcfProxy`1:CreateProxyCore : Trying programmatic configuration of EntityServer
31 : 23/03/2012 09:27:18 :  : IdeaBlade.Core.Composition.CompositionHost:CheckMultiExport : CompositionContext: '-IbDefault-' - Probed for non-default 'IKnownTypeProvider' and found no matching exports.
32 : 23/03/2012 09:27:18 :  : IdeaBlade.EntityModel.RemoteServiceFns:AddSerializationBehavior : Using DC serializer for EntityServer
33 : 23/03/2012 09:27:18 :  : IdeaBlade.EntityModel.WcfProxy`1:CreateProxyCore : Created proxy to EntityServer using Uri http://127.0.0.1:9009/EntityServer.svc
34 : 23/03/2012 09:27:28 :  : IdeaBlade.Core.Composition.CompositionHost:CheckSingleExport : CompositionContext: '-IbDefault-' - Probed for any 'IAuthenticationProvider' and found no matching exports.
The thread '<Thread Ended>' (0x414) has exited with code 0 (0x0).
35 : 23/03/2012 09:27:30 :  : Cocktail.Composition:WarnIfNotConfigured : WARNING: Composition has not been configured. Not all types may be available.
36 : 23/03/2012 09:27:30 : Dev : Cocktail.Composition:WarnIfNotConfigured : WARNING: Composition has not been configured. Not all types may be available.
37 : 23/03/2012 09:27:30 : Dev : Cocktail.Composition:WarnIfNotConfigured : WARNING: Composition has not been configured. Not all types may be available.
38 : 23/03/2012 09:27:30 : Dev : Cocktail.AuthenticationService:OnLoggedIn : Successfully performed user login with connection info: DesignTime, IsFake=False.
39 : 23/03/2012 09:27:33 : Dev : Cocktail.Composition:WarnIfNotConfigured : WARNING: Composition has not been configured. Not all types may be available.
40 : 23/03/2012 09:27:40 : Dev : IdeaBlade.EntityModel.EntityMetadataStore:LoadMetadataFromEmbeddedResources : No metadata resources found in 'DataModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
41 : 23/03/2012 09:27:40 : Dev : IdeaBlade.Core.Composition.CompositionHost:CheckSingleExport : CompositionContext: '-IbDefault-' - Probed for non-default 'IDataSourceKeyResolver' and found no matching exports.
42 : 23/03/2012 09:27:40 : Dev : IdeaBlade.Core.Composition.CompositionHost:CheckMultiExport : CompositionContext: '-IbDefault-' - Probed for any 'IIdGenerator' and found 'IdeaBlade.EntityModel.StoreGeneratedIdGenerator'.
A first chance exception of type 'IdeaBlade.EntityModel.LoginException' occurred in IdeaBlade.EntityModel.dll
Step into: Stepping over non-user code 'System.ComponentModel.Composition.ReflectionModel.ReflectionComposablePart.CreateInstance'
Step into: Stepping over non-user code 'System.ComponentModel.Composition.Hosting.ImportEngine.PartManager.TryOnComposed'
Step into: Stepping over non-user code 'System.ComponentModel.Composition.Hosting.ImportEngine.TrySatisfyImportsStateMachine'
Step into: Stepping over non-user code 'System.ComponentModel.Composition.Hosting.ImportEngine.TrySatisfyImports'
Step into: Stepping over non-user code 'System.ComponentModel.Composition.Hosting.ImportEngine.SatisfyImports'
Step into: Stepping over non-user code 'System.ComponentModel.Composition.Hosting.CompositionServices.GetExportedValueFromComposedPart'
A first chance exception of type 'System.ComponentModel.Composition.CompositionException' occurred in System.ComponentModel.Composition.dll
Step into: Stepping over non-user code 'MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen'
The program '[3768] LabelLogicLiveAdmin.vshost.exe: Managed (v4.0.30319)' has exited with code 0 (0x0).

Back to Top
mgood View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
Post Options Post Options   Quote mgood Quote  Post ReplyReply Direct Link To This Post Posted: 23-Mar-2012 at 3:45am
I stopped reading at this post. A number of issues here.
First of all, you are the second person I'm aware of, who decides to override the Configure method and completely neglects to call the base method. Such a thing normally only works if the base method has an empty body! In this case, the base Configure method contains the guts of the configuration, which you simply skipped. It should be pretty obvious that things won't work.
 
Second, you then proceed with creating your own CompositionContainer. Again, you are the second person doing this. Where is this coming from? Please help me understand why you thought you had to create your own CompositionContainer. I want to fix whatever got you down this road. Have you studied TempHire? Did you see it create it's own container anywhere? 
 
All you need from your Configure method are the following two lines and they belong in PrepareCompositionContainer. DON'T FORGET TO CALL base.PrepareCompositionContainer when you override the method. Also, you don't need .With(ConnectionOptions.Default.Name). That's redundant. If you don't specify anything it automatically uses the default. That's what a default is usually for.
 
batch.AddExportedValue<IEntityManagerProvider<LabelLogicEntities>>(new EntityManagerProvider<LabelLogicEntities>())
batch.AddExportedValue<IAuthenticationService>(new AuthenticationService());
 
Third, I see this too often unfortunatley. The kind of logic you are performing in the ShellViewModel constructor, does not belong in a constructor. A construtor is not a method that gets called on a completely constructed object. It gets called DURING the construction. It's not safe to do this kind of logic in the middle of construction. It just isn't.
 
This stuff belongs into the OnInitialize method that you inherit from Conductor<IScreen>. Override OnInitialize and perform any initialization that involves querying the database etc. It gets called once when the ViewModel is first activated.
 
I think that's enough to fix for now.
 
Originally posted by Siyfion

It was crashing in another place, but to try it out I moved some code into my ShellViewModel constructor, so it now looks like this:

    [Export(typeof(IShell))]
    class ShellViewModel : Conductor<IScreen>, IShell
    {
        private readonly IAuthenticationService _authenticationService;

        [ImportingConstructor]
        public ShellViewModel(IAuthenticationService authenticationService)
        {
            _authenticationService = authenticationService;

            var loginCredential = new LoginCredential("Dev", null, null);
            _authenticationService.Login(loginCredential);

            var userRepository = IoC.Get<IUserRepository>();
            var owner = userRepository.CreateOwner();
            var saveResult = userRepository.SaveSync();

            ShowSheetCreation();
        }

        public void ShowSheetCreation()
        {
            var sheetCreation = IoC.Get<ISheetCreation>();
            ActivateItem(sheetCreation);
        }

        private string _title;
        public string Title
        {
            get { return _title; }
            set
            {
                if (_title == value) return;
                _title = value;
                NotifyOfPropertyChange(() => Title);
            }
        }

        public void SetTitle(string title)
        {
            if (!string.IsNullOrEmpty(title))
                Title = title;
        }
    }

And my AppBootstrapper:

        protected override void Configure()
        {
            _container =
                new CompositionContainer(
                    new AggregateCatalog(
                        AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()));

            var batch = new CompositionBatch();
            batch.AddExportedValue<IWindowManager>(new WindowManager());
            batch.AddExportedValue<IEventAggregator>(new EventAggregator());
            batch.AddExportedValue<IEntityManagerProvider<LabelLogicEntities>>(
                new EntityManagerProvider<LabelLogicEntities>().With(ConnectionOptions.Default.Name));
            batch.AddExportedValue<IAuthenticationService>(
                new AuthenticationService().With(ConnectionOptions.Default.Name));
            batch.AddExportedValue(_container);

            _container.Compose(batch);

            Application.ShutdownMode = ShutdownMode.OnExplicitShutdown;
        }
Back to Top
Siyfion View Drop Down
Groupie
Groupie
Avatar

Joined: 22-Mar-2012
Location: Bristol, UK
Posts: 47
Post Options Post Options   Quote Siyfion Quote  Post ReplyReply Direct Link To This Post Posted: 23-Mar-2012 at 5:33am
Ok, I'll discuss the points you raised one at a time to keep things simple:

First of all, you are the second person I'm aware of, who decides to override the Configure method and completely neglects to call the base method. Such a thing normally only works if the base method has an empty body! In this case, the base Configure method contains the guts of the configuration, which you simply skipped. It should be pretty obvious that things won't work.

True, I wasn't calling the base.Configure() method and I should have been. However, it didn't make any difference as the Bootstrapper.Configure() method is empty, and my AppBootstrapper inherited directly from Bootstrapper not Cocktails' FrameworkBootstrapper.

The reason for this is simple, the documentation on the FrameworkBootstrapper<T> located here: http://drc.ideablade.com/xwiki/bin/view/Documentation/cocktail-application-bootstrapper doesn't provide any clue as to the functionality is provides over and above the default CaliburnMicro Bootstrapper class.

Second, you then proceed with creating your own CompositionContainer. Again, you are the second person doing this. Where is this coming from? Please help me understand why you thought you had to create your own CompositionContainer. I want to fix whatever got you down this road. Have you studied TempHire? Did you see it create it's own container anywhere?

As per my previous comment, not knowing what FrameworkBootstrapper provides that Bootstrapper does not, I followed through the CaliburnMicro documentation, leading me here:  http://caliburnmicro.codeplex.com/wikipage?title=Customizing%20The%20Bootstrapper&referringTitle=Documentation Which goes over the basic MEF composition, producing very similar code to what I had.

Third, I see this too often unfortunatley. The kind of logic you are performing in the ShellViewModel constructor, does not belong in a constructor. A construtor is not a method that gets called on a completely constructed object. It gets called DURING the construction. It's not safe to do this kind of logic in the middle of construction. It just isn't.

Again, in one of my previous posts I stated that I moved some stuff into the constructor of the ShellViewModel so that it was easier to debug, what with it being all in one place. Indeed, afterwards it will go into the OnInitialize() method.


Doing it this way, I had to manually do the following:

protected override void OnInitialize()
        {
            var entityManagerProvider = IoC.Get<IEntityManagerProvider<LabelLogicEntities>>();
            entityManagerProvider.Manager.Connect();

            var loginCredential = new LoginCredential("Dev", null, null);
            _authenticationService.Login(loginCredential);

    // ********** NOTE THIS LINE  ************* //
            entityManagerProvider.Manager.AuthenticationContext = _authenticationService.AuthenticationContext;

            ShowSheetCreation();

            base.OnInitialize();
        }

I'm assuming if I switch to using the FrameworkBootstrapper I can get rid of some of this code? ie. Do I need to manually call Connect()? Do I need to manually assign the _authenticationService.AuthenticationContext to the Manager.AuthenticationContext?

The main reason I feel that I have fallen into these issues is due to the lack of proper documentation regarding the classes discussed, and very little documentation on the TempHire project.

Also, one could argue that the HappyHour Tutorial is a brilliant step-by-step guide, however it's very simplistic and focuses much more on CaliburnMicro than "Cocktail" per se. The TempHire goes the other way.... Too complex and hardly any documentation to go through it.

Perhaps another "middle ground" tutorial would be a good addition? Especially one that goes over the Cocktail concepts explicitly, rather than CaliburnMicro (like HappyHour). A simple solution that uses Repositories, EntityManagerProviders, etc.

Back to Top
mgood View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
Post Options Post Options   Quote mgood Quote  Post ReplyReply Direct Link To This Post Posted: 23-Mar-2012 at 6:06am
Siyfion,
Yes, the documentation is early stage. That's one reason Cocktail hasn't hit v1 yet. The short answer is yes, you have to jump through all these hoops, because you didn't extend from FrameworkBootstrapper. My bad, I didn't notice that part.
 
FrameworkBootstrapper does all the additional work that the Caliburn Bootstrapper doesn't do out of the box. It creates the container, makes sure things like the WindowManager, EventAggregator etc. get into the container and it configures all the DevForce hooks so that it all works together.
 
To answer your questions. No, you don't need to manually call Connect, provided you don't use a ConnectionOptions object that has ShouldConnect set to false. You also don't need to manually assign the AuthenticationContext. Once you extend from the FrameworkBootstrapper, everything bootstrapps automatically and Cocktail makes sure that the EntityManagers are configured and authenticated. This is the value add of Cocktail and it starts with the FrameworkBootstrapper.
 
I hear you on the tutorial front. Happy Hour is going to have more lessons that ease you into Cocktail. TempHire is the end product where an experienced Cocktail developer might land and yes, it also needs documentation. It's all a matter of limited time and resources unfortunately, but we'll get there.
Back to Top
 Post Reply Post Reply Page  12>

Forum Jump Forum Permissions View Drop Down