| Author |
Share Topic Topic Search Topic Options
|
pponzano
Senior Member
Joined: 28-Apr-2011
Location: Italy
Posts: 165
|
Post Options
Quote Reply
Topic: Link For Authentication Posted: 24-Jan-2012 at 2:07am |
Hello Marcel, I've checked... one of my EntityManagerProvider is
public class EntityManagerProvider : BaseEntityManagerProvider<myEntities>
{
protected override myEntities CreateEntityManager()
{
return new myEntities();
}
}
I've also tried putting [Export] and [Export(typeof(EntityManagerProvider )] but I always get Could not locate any instances of contract my.ViewModels.ShellViewModel where ShellViewModel is defined as
[Export]
public class ShellViewModel : Conductor<IScreen>.Collection.OneActive, IHandle<ActivateWorkspaceMessage>, ITaggable
{
private readonly Lazy<LoginViewModel> _login;
private readonly Lazy<WorkspaceViewModel> _workspace;
private IApplicationRepository _repository;
[ImportingConstructor]
public ShellViewModel(IEventAggregator eventAggregator, Lazy<LoginViewModel> login,
Lazy<WorkspaceViewModel> workspace, IApplicationRepository repository)
{
this.DisplayName = ExtendedDescription;
eventAggregator.Subscribe(this);
_login = login;
_workspace = workspace;
_repository = repository;
} I've notice I don't have a EntityManagerProviderFactory, is this the problem? Thanks
|
 |
pponzano
Senior Member
Joined: 28-Apr-2011
Location: Italy
Posts: 165
|
Post Options
Quote Reply
Posted: 24-Jan-2012 at 1:50am |
Hello Marcel, I'll take a look in a short... what I did was based on the point Sharing a single EntityManagerProvider btw I'll take a look and give you a feedback Thanks
|
 |
mgood
IdeaBlade
Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
|
Post Options
Quote Reply
Posted: 24-Jan-2012 at 1:09am |
Well, then there's something wrong in how you have things setup. You do not need to set batch.AddExportedValue(). My hunch is you forgot to export the EntityManagerProviders, so MEF can't instantiate your repositories, because it can't find the appropriate EntityManagerProvider. Check your output window, you should see MEF error messages that tell you what's missing.
|
 |
pponzano
Senior Member
Joined: 28-Apr-2011
Location: Italy
Posts: 165
|
Post Options
Quote Reply
Posted: 24-Jan-2012 at 12:14am |
Excuse me Marcel, the code I pasted below is relative to protected override void InitializeCompositionBatch(CompositionBatch batch) If I don't add the exported value on my repositories they won't be ignected to my models... for example one repository is [Export(typeof(IExportRepository))] public class ExportRepository : IExportRepository and it's called as[Import] private IExportRepository_repository; [ImportingConstructor] public ShellViewModel(IEventAggregator eventAggregator, Lazy<LoginViewModel> login, Lazy<WorkspaceViewModel> workspace,IExportRepository exportRepository) but if I don't set the batch.AddExportedValue<IExportRepository>(iExportRepository); in BootStrapper it won't work...
|
 |
mgood
IdeaBlade
Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
|
Post Options
Quote Reply
Posted: 23-Jan-2012 at 12:24am |
No, that doesn't look right. You are hardwiring all your dependencies. One never explicity calls LinkForAuthentication. DAF uses MEF to wire up your dependencies and handles things like LinkForAuthentication for you. Use [ImportingConstructor] on your repositories and let MEF satisfy the dependencies for you. How to do this stuff is explained in the documentation on CodePlex. Follow that structure. var admin = new AuthenticationService<Entities>(provider.Manager); Don't pass a hardwired manager to the AuthenticationService. It will grab the correct one automatically. The ability to pass a specific EntityManager is for testing purposes. Learn the concept of inversion of control. The point of IoC is you don't hardwire the dependencies like you do here. You let the IoC container (MEF in this case) satisfy the dependencies. I crossed out the parts to don't seem to need below. Use the [Export] attribute on your repository classes to register them in the MEF container and use [ImportingConstructor] on the constructor to tell MEF to inject the EntityManagerProvider. var provider = new EntityManagerProvider();
var chProvider = new CHEntityManagerProvider();
var ExportProvider = new ExportEntityManagerProvider();
varRepository = new myRepository(provider);
var chRepository = new CHRepository(chProvider);
var ExportRepository = new ExportRepository(ExportProvider);
batch.AddExportedValue<IApplicationRepository>(Repository);
batch.AddExportedValue<ICHApplicationRepository>(chRepository);
batch.AddExportedValue<IExportRepository>(ExportRepository);
var admin = new AuthenticationService<Entities>(provider.Manager); chProvider.Manager.LinkForAuthentication(provider); ExportProvider.Manager.LinkForAuthentication(provider);
batch.AddExportedValue<IAuthenticationService>(admin);
|
 |
pponzano
Senior Member
Joined: 28-Apr-2011
Location: Italy
Posts: 165
|
Post Options
Quote Reply
Posted: 23-Jan-2012 at 12:04am |
Hello Marcel, when you say DAF is taking care of everything you mean of logging out? since I use DAF.... in my InitializeCompositionBatch it's
var provider = new EntityManagerProvider();
var chProvider = new CHEntityManagerProvider();
var ExportProvider = new ExportEntityManagerProvider();
var Repository = new myRepository(provider);
var chRepository = new CHRepository(chProvider);
var ExportRepository = new ExportRepository(ExportProvider);
batch.AddExportedValue<IApplicationRepository>(Repository);
batch.AddExportedValue<ICHApplicationRepository>(chRepository);
batch.AddExportedValue<IExportRepository>(ExportRepository);
var admin = new AuthenticationService<Entities>(provider.Manager);
chProvider.Manager.LinkForAuthentication(provider);
ExportProvider.Manager.LinkForAuthentication(provider);
batch.AddExportedValue<IAuthenticationService>(admin); is it ok? Thanks
|
 |
mgood
IdeaBlade
Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
|
Post Options
Quote Reply
Posted: 20-Jan-2012 at 10:46am |
Originally posted by pponzano
excuse me, I'm facing a similar situation... I've got 3 model's one is authenticated and the other 2 no... I've not used the LinkAuthentication, how should I put it? inside my IEntityLoginManager in the
public System.Security.Principal.IPrincipal Login(ILoginCredential credential, EntityManager entityManager) { } ??
Thanks Paolo
|
LinkForAuthentication is used on the client, so that only one EntityManager has to login and the other EntityManagers simply link themselves to the same session. Generally, you have a master EntityManager that is used to login at the beginning of the application and then any other EntityManager created throughout the lifecycle of the application is linked to the Master EntityManager's session. var master = new SomeEntityManager(); master.Login(....) // or LoginAsync() var em = new SomeOtherEntityManager(); em.LinkForAuthentication(master); Logout gets a little trickier, because once an EntityManager has a session you have to call Logout on it before you can link it to another session, so generally the safe approach is to just release all EntityManagers when the application logs out and create new ones when a new user logs in. If you use the DevForce Application Framework, all of this is taken care of for you by the AuthenticationService<T> and BaseEntityManagerProvider<T>. The original poster was simply missing the LoginManager on the server for some of his CompositionContexts, so the login didn't actually properly work on the server. The client was doing the right thing all along, since he is using DAF.
|
 |
pponzano
Senior Member
Joined: 28-Apr-2011
Location: Italy
Posts: 165
|
Post Options
Quote Reply
Posted: 20-Jan-2012 at 8:46am |
|
excuse me, I'm facing a similar situation... I've got 3 model's one is authenticated and the other 2 no... I've not used the LinkAuthentication, how should I put it? inside my IEntityLoginManager in the
public System.Security.Principal.IPrincipal Login(ILoginCredential credential, EntityManager entityManager) { } ??
Thanks Paolo
|
 |
mgood
IdeaBlade
Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
|
Post Options
Quote Reply
Posted: 06-Jan-2012 at 4:59am |
|
Yep, that was gonna be my next direction. It got clear that something wasn't right on the server. Glad you figured it out.
|
 |
smi-mark
DevForce MVP
Joined: 24-Feb-2009
Location: Dallas, Texas
Posts: 343
|
Post Options
Quote Reply
Posted: 05-Jan-2012 at 10:21am |
|
Figured it out!!
I'm using a CompositionContextResolver to assign types to the real/fake login manager.
Both of my LoginManager's have PartNotDiscoverable and then I create the context and pass which one it should use.
My second model did not know about the LoginManager. Fixed now!
I noticed this line in the debuglog, which pointed me in the right direction:
<entry id="92" timestamp="2012-01-05T10:26:34" username="" source="IdeaBlade.EntityModel.Server.SessionManager:GetLoginManager">No Login Manager found. AllowAnonymousLogin is disabled, no logins will be accepted.</entry>
Edited by smi-mark - 05-Jan-2012 at 10:27am
|
 |
smi-mark
DevForce MVP
Joined: 24-Feb-2009
Location: Dallas, Texas
Posts: 343
|
Post Options
Quote Reply
Posted: 05-Jan-2012 at 8:35am |
Hi Marcel, I have confirmed that it is indeed being linked, see below screens: This is being called from LinkAuthentication in BaseEntityManagerProvider.cs This is the Manager that it will be linked to. As you can see, it is logged in and has a principal.  This is the target Manager that is going to be linked. As you can see initially it is not logged in and does not have a principal.  This is the target Manager immediately after the LinkForAuthentication call. As you can see it is now logged in with a principal.  I do not have a custom IAuthenticationProvider, and my AuthenticationService only overrides OnLoggedIn and OnLoggedOut to publish an event.
|
 |
mgood
IdeaBlade
Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
|
Post Options
Quote Reply
Posted: 05-Jan-2012 at 12:31am |
Mark, Difficult to say what's going on without seeing some of your code. I can successfully demonstrate that this works under normal circumstances. From your description it's pretty clear that the EntityManager you are calling SaveChanges on is in fact not linked. You could verify this by checking the IsLoggedIn property and/or the Principal property before calling SaveChanges. It should say true and it should return the current principal. Perhaps you can send me your AuthenticationService, so I can see what you have customized. My first hunch is that something is going wrong there. There's also IAuthenticationProvider which DevForce looks for to automatically link EntityManagers that are not linked yet. DAF automatically injects an AuthenticationProvider during configuration if it doesn't already see one in the MEF container. Do you perhaps have your own implementation of IAuthenticationProvider? Maybe we have to debug this over a WebEx when I'm back in the office next week. Marcel
|
 |
smi-mark
DevForce MVP
Joined: 24-Feb-2009
Location: Dallas, Texas
Posts: 343
|
Post Options
Quote Reply
Posted: 04-Jan-2012 at 3:38pm |
|
I've disable AnonymousLogin now and I'm getting "Support for Anonymous logins is not enabled." so something is definitely not linking right.
I am using Marcel's framework as I stated above, so the BaseEntityManagerProvider should be calling LinkAuthentication on my custom AuthenticationService (which it is)
|
 |
smi-mark
DevForce MVP
Joined: 24-Feb-2009
Location: Dallas, Texas
Posts: 343
|
Post Options
Quote Reply
Posted: 04-Jan-2012 at 3:29pm |
|
I have two models, and I'm using LinkForAuthentication using the AuthenticationService in the DevForce Application Framework.
I have confirmed link is being called, but when my EntityServerSaveInterceptor is being called on the server, for the second model, the principal is showing anonymous, and not the correct one. Any suggestions?
|
 |