Author |
Share Topic Topic Search Topic Options
|
pponzano
Senior Member
Joined: 28-Apr-2011
Location: Italy
Posts: 165
|
Post Options
Quote Reply
Topic: Getting an Object not set exception as I uncomment Export Posted: 23-Feb-2012 at 9:04am |
Hello, I looked at the sample TempHire and I decided to use that login method (I used a different one, but I like your more), I got a problem with
[Export(typeof(IAuthenticationService))]
[Export(typeof(IUserService))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class myAuthenticationService : AuthenticationService<myEntities>, IUserService
{
public IFUser CurrentUser
{
get { return Principal as IFUser; }
}
protected override void OnLoggedIn()
{
base.OnLoggedIn();
EventFns.Publish(new LoggedInMessage(CurrentUser));
}
protected override void OnLoggedOut()
{
base.OnLoggedOut();
EventFns.Publish(new LoggedOutMessage());
}
} If I comment [Export(typeof(IAuthenticationService))] it starts (but crashes later,telling that it cannot find a viewmodel for ShellViewModel)... the debuglog.xml tells
2012-02-23 |
18:02:50 |
|
Cocktail.PartLocator`1:WriteTrace |
Probed for service with contract IAuthenticationService and found
my.Authentication.myAuthenticationService |
2012-02-23 |
18:02:50 |
|
Cocktail.EntityManagerProviderBase`1:get_EntityManagerDelegates |
Probed for EntityManagerDelegate and found no matchting exports. |
2012-02-23 |
18:02:50 |
|
Cocktail.PartLocator`1:WriteTrace |
Probed for service with contract IEntityManagerProvider`1 and found no
matching exports |
so it seems to have it... what can I look? Thanks
|
|
mgood
IdeaBlade
Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
|
Post Options
Quote Reply
Posted: 23-Feb-2012 at 10:08am |
pponzano, I'm not clear on whether you commented it out in TempHire or your own application. But TempHire no longer works if you comment it out there. The reason for that is the authentication service is injected in the ShellViewModel via the Cocktail IAuthenticationService interface. Furthermore, Cocktail looks for this interface to properly authenticate all EntityManagers, so you MUST export the AuthenticationService via IAuthenticationService. It doesn't work any other way. Are you sure those log entries are from the most recent run? You have another issue there. It can't find an EntityManagerProvider. The AuthenticationService is gonna need an EntityManagerProvider to work. Marcel
|
|
pponzano
Senior Member
Joined: 28-Apr-2011
Location: Italy
Posts: 165
|
Post Options
Quote Reply
Posted: 23-Feb-2012 at 11:22pm |
Hello Marcel, when I comment out in my application it works... now I check again and let you know...Thanks
|
|
pponzano
Senior Member
Joined: 28-Apr-2011
Location: Italy
Posts: 165
|
Post Options
Quote Reply
Posted: 23-Feb-2012 at 11:27pm |
I've found this 2012-02-24 08:25:06 IdeaBlade.Core.Composition.CompositionHost:CheckSingleExport CompositionContext: '-IbDefault-' - Probed for default 'IDataSourceKeyResolver' and found 'IdeaBlade.EntityModel.DefaultDataSourceKeyResolver'. 2012-02-24 08:25:06 IdeaBlade.EntityModel.WcfProxy`1:CreateProxyCore Trying automatic configuration of EntityService 2012-02-24 08:25:07 IdeaBlade.EntityModel.RemoteServiceFns:AddSerializationBehavior Using DC serializer for EntityService 2012-02-24 08:25:07 IdeaBlade.Core.Composition.CompositionHost:CheckSingleExport CompositionContext: '-IbDefault-' - Probed for any 'ServiceProxyEvents' and found 'IdeaBlade.EntityModel.ServiceProxyEvents'. 2012-02-24 08:25:07 IdeaBlade.EntityModel.WcfProxy`1:CreateProxyCore Created proxy to EntityService using Uri http://localhost:9009/EntityService.svc 2012-02-24 08:25:10 IdeaBlade.EntityModel.WcfProxy`1:CreateProxyCore Trying automatic configuration of EntityServer 2012-02-24 08:25:10 IdeaBlade.EntityModel.KnownTypeHelper:<GetMarkedKnownTypes>b__13 Probed for known types and found my.DomainModel.IFUser 2012-02-24 08:25:10 IdeaBlade.Core.Composition.CompositionHost:CheckMultiExport CompositionContext: '-IbDefault-' - Probed for non-default 'IKnownTypeProvider' and found no matching exports. 2012-02-24 08:25:10 IdeaBlade.EntityModel.RemoteServiceFns:AddSerializationBehavior Using DC serializer for EntityServer 2012-02-24 08:25:10 IdeaBlade.EntityModel.WcfProxy`1:CreateProxyCore Created proxy to EntityServer using Uri http://localhost:9009/EntityServer.svc/ 2012-02-24 08:25:12 Cocktail.PartLocator`1:WriteTrace Probed for service with contract IAuthenticationService and found my.Authentication.myAuthenticationService 2012-02-24 08:25:12 Cocktail.EntityManagerProviderBase`1:get_EntityManagerDelegates Probed for EntityManagerDelegate and found no matchting exports. 2012-02-24 08:25:12 Cocktail.PartLocator`1:WriteTrace Probed for service with contract IEntityManagerProvider`1 and found no matching exports and as you've told before it doesn't find an IEntityManagerProvider.. I check why this happen
|
|
pponzano
Senior Member
Joined: 28-Apr-2011
Location: Italy
Posts: 165
|
Post Options
Quote Reply
Posted: 24-Feb-2012 at 1:56am |
Hello, I've fixed this part implementing the EntityManagerProviderFactory<T> as you've done in your sample... I've got another question, in my DAF based implementation I used an IApplicationRepository that exposes all the methods my EntityManager contains... and in my bootstrapper I add an batch.AddExportedValue<IApplicationRepository>(myEntity) have I to continue do so? Here's mine compositionBatch (curerntly I've 3 modules ... I wish not to have to specify them so if I add a 4th I don't have to redeploy the application) protected override void PrepareCompositionContainer(CompositionBatch batch) { base.PrepareCompositionContainer(batch); var catalog = new AggregateCatalog(AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()); container = new CompositionContainer(catalog); var provider = new my.DomainModel.EntityManagerProvider(); var chProvider = new my2EntityManagerProvider(); var adminProvider = new AdminEntityManagerProvider(); var chDefaultProvider = new my.DomainModel.my2.EntityManagerProvider(); var chDefaultRepository = new my.DomainModel.my2.CHmyRepository(chDefaultProvider); batch.AddExportedValue<ICHApplicationRepository>(chDefaultRepository); repository = new my.DomainModel.myRepository(provider); var chRepository = new mymy2Repository(chProvider); var adminRepository = new myAdminRepository(adminProvider); batch.AddExportedValue<my.DomainModel.IApplicationRepository>(repository); batch.AddExportedValue<Imy2ApplicationRepository>(chRepository); batch.AddExportedValue<IAdminApplicationRepository>(adminRepository); batch.AddExportedValue(container); var myViewModelFactory = new myViewModelFactory(); batch.AddExportedValue(myViewModelFactory); batch.AddExportedValue(App.SharedObject); //batch.AddExportedValue(EventAggregator); container.Compose(batch); } Thanks in advance
|
|
mgood
IdeaBlade
Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
|
Post Options
Quote Reply
Posted: 24-Feb-2012 at 3:46pm |
What's going on here? Why are you creating a CompositionContainer and Catalog in PrepareCompositionContainer. Look at TempHire, you don't see me doing anything of this sort. Cocktail already creates the container and catalog for you. Everything in your code decorated with an [Export] attribute is automatically added to the catalog. The only reason PrepareCompositionContainer is here is to allow you to add specific shared things to the container that are not marked with [Export] attributes. You just add them to the provided CompositionBatch and Cocktail will compose them into the container for you. This looks like you went off track somewhere. You don't have to manually add all your repositories etc to the container. Just mark them with the [Export] attribute. This way if you add repositories etc. for new models, you don't have to constantly modify the bootstrapper. Look at how very little I have in the TempHire bootstrapper. I recommend you take a deep look at TempHire and follow the patterns you see there. I have a feeling that you've gone down a dark rabbit hole.
|
|
pponzano
Senior Member
Joined: 28-Apr-2011
Location: Italy
Posts: 165
|
Post Options
Quote Reply
Posted: 28-Feb-2012 at 7:56am |
Hello Marcel, I'm tring to fix things up... I've got a Module called Admin,if I remove from bootstrapper it won't be called the costructor of the viewmodels.. My Admin module has a DomainModel.Admin.Client and DomainModel.Admin.Server My WPF project reference Admin (that itself reference DomainModel.Admin.Client) In the .Client I've defined AdminRepository
[Export(typeof(IAdminApplicationRepository))]
public class AdminRepository : RepositoryBase<AdminEntities>, IAdminApplicationRepository
{
private myUser user = null;
private readonly IEntityManagerProvider<AdminEntities> entityManagerProvider;
[ImportingConstructor]
public AdminRepository([Import(RequiredCreationPolicy = CreationPolicy.NonShared)] IEntityManagerProvider<AdminEntities>
entityManagerProvider) : base(entityManagerProvider)
{
this.entityManagerProvider = entityManagerProvider;
user = Manager.Principal as myUser;
} //THIS IS NOT CALLED IF I COMMENT OUT in bootstrapper
Interface :
public interface IAdminApplicationRepository
{ ..ony methods that are called from the module
} Provider
public class AdminEntityManagerProvider : EntityManagerProviderBase<DOMEAdminEntities>
{
protected override DOMEAdminEntities CreateEntityManager()
{
return new DOMEAdminEntities();
}
}
I've also tried to create a Factory inside the admin module that's
namespace my.Modules.Admin
{
public class EntityManagerProviderFactory
{
[Export]
public IEntityManagerProvider<AdminEntities> AdminireEntityManagerProvider
{
get
{
return new AdminEntityManagerProvider();
}
}
}
}
I think I'm missing something ....I think that beign this an external assembly it doesn't look inside it , even if the log tells that Assembly 'my.Modules.Admin, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null' added to PartsCatalog Assembly 'my.DomainModel.Adminsitration.Client, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null' added to PartsCatalog Any suggestion?
|
|
mgood
IdeaBlade
Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
|
Post Options
Quote Reply
Posted: 28-Feb-2012 at 8:52am |
Please post the contents of the Output Window from Visual Studio. I need to see everything to get an idea of what's happening.
|
|
pponzano
Senior Member
Joined: 28-Apr-2011
Location: Italy
Posts: 165
|
Post Options
Quote Reply
Posted: 28-Feb-2012 at 9:05am |
|
|
mgood
IdeaBlade
Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
|
Post Options
Quote Reply
Posted: 28-Feb-2012 at 10:15am |
I'll take a look. Before I do, I noticed something else. [ImportingConstructor] public AdminRepository([Import(RequiredCreationPolicy = CreationPolicy.NonShared)] IEntityManagerProvider<AdminEntities> entityManagerProvider) : base(entityManagerProvider) { this.entityManagerProvider = entityManagerProvider; user = Manager.Principal as myUser; } // You shouldn't trigger instantiation of an EntityManager in a constructor. When your constructor is called you'll be in the middle of MEF composition. The container isn't ready and your object graph hasn't finished constructing and composing. The EntityManager itself is trying to find things in the container. You may get lucky and it finds it or you may get very unlucky depending on your application's unique composition signature and get errors down the road in unexpected places. Constructors should ALWAYS be limited to trivial object initialization. Things as big and complex as an EntityManager should be lazy instantiated outside of the constructor. Second, you shouldn't get your current user from Manager.Principal. This property is actually going to be deprecated in the next release of DevForce. It never should have been there. You should always get your current user from a service. See TempHire and search for IUserService to see an example. TempHire isn't currently consuming this service, but it demonstrates how to implement such a thing on top of the AuthenticationService. It would just inject IUserService into ViewModels that need the current user. Also, don't store the user in your ViewModel. You may not be logged in at the time and eventually your application may support logout. Sooner or later you'll find yourself in a cleanup mess. Always get the principal fresh from the user service when you need it to make sure you get the correct current user.
|
|
mgood
IdeaBlade
Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
|
Post Options
Quote Reply
Posted: 28-Feb-2012 at 10:25am |
I took a look at your output and it fails to load one of your assemblies. That would be the first thing to investigate. 11 : 28/02/2012 17:59:42 : : IdeaBlade.Core.Composition.PartsCatalog:LoadCatalog : Error loading assembly 'C:\Projects\my\my\my\bin\Debug\my.exe.mancompanyest' for PartsCatalog: Error with file my.exe.mancompanyest.
|
|
pponzano
Senior Member
Joined: 28-Apr-2011
Location: Italy
Posts: 165
|
Post Options
Quote Reply
Posted: 28-Feb-2012 at 12:16pm |
Hello Marcel, I've replaced my project name with company.... the error is 11 : 28/02/2012 17:59:42 : : IdeaBlade.Core.Composition. PartsCatalog:LoadCatalog : Error loading assembly 'C:\Projects\my\my\my\bin\Debug\mymainWPFapp.exe.manifest' for PartsCatalog: Error with file mymainWPFapp.exe.manifest.
I've taken this part from tempfire (I'm not in the office rigth now, can write you tomorrow morning but you'll be out of office!) to fix the first thing what should I do?
Thanks
|
|
mgood
IdeaBlade
Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
|
Post Options
Quote Reply
Posted: 28-Feb-2012 at 1:39pm |
Not sure what you took from TempHire. It looks like there's something going on with your manifest. You may want to flush your bin directories. You have to be careful in WPF, because MEF just scoops up everything in your bin folder. If you have some old assemblies in there, they are still getting probed. Copy flush.cmd from the Cocktail folder to the root of your solution. Close your solution and Visual Studio and then run flush.cmd from the root of your solution. This will clean up all the clutter. Then build and run again and see if anything changes.
|
|
pponzano
Senior Member
Joined: 28-Apr-2011
Location: Italy
Posts: 165
|
Post Options
Quote Reply
Posted: 29-Feb-2012 at 12:38am |
Excuse me Marcel,
I've checked the .manifest file but why is Ideablade tring to load a .manifest as an assembly?
I can't do much with .manifest file, it's auto generated and I've no control over it...
Thanks
|
|
pponzano
Senior Member
Joined: 28-Apr-2011
Location: Italy
Posts: 165
|
Post Options
Quote Reply
Posted: 29-Feb-2012 at 3:28am |
Hello Marcel, maybe I've found something related to the problem I've... I was tring to fix the IUserService here's what I've spotted My application is in the form MAIN_WPF_APP (1) | WPF.MODULE.JOB (2) | WPF.DOMAINMODEL.JOB.Client (3) | WPF.DOMAINMODEL.JOB.Server | DB (finally!) I've noticed that in my viewmodel (2) if I define
[Import]
IUserService UserSevice { get; set; }
when I call the LoadData() method , UserService is properly valorized In my (3) repository it's null... why this happen?
|
|
mgood
IdeaBlade
Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
|
Post Options
Quote Reply
Posted: 29-Feb-2012 at 8:14am |
I'm afraid, but without looking at your entire solution, I'm at a loss as to what's going on here. There could be a number of reasons why your composition is failing. I'm going back to your original bootstrapper where you did some strange things with creating your own container etc. For all a I know there could be something similar somewhere else in your application. As you can see, TempHire doesn't have any issue with the manifest or anything similar to what you are experiencing. Troubleshooting your application at this level, though, is beyond the scope of this forum. That would take significant time on my end, which I would have to bill for. I'm actually going to be in Germany and Switzerland next month. If you'd like to use some of our consulting services, we could work together and try to troubleshoot this over WebEx. At least we would be in the same timezone.
|
|