Public information

  • Thread starter Thread starter Gerrit
  • Start date Start date
G

Gerrit

Hallo,

In my application, the user must logon with a username and a password. In
all the tables in my database, there is a field user. By saving new or
changed records, the username is writed to that field.

Now I have a class Session with the User-information.
By opening the program, I have code like this on the mainform:

Session sess = new Session().
sess.UserName = "John";

When I open a new form, then I do this:

frmNew frm = new frmNew(sess);

When I write to the Database, I do this:

Article art = new Article(sess);

etc.

This is working, but I was asking by myself, that maybe there must be
another way to do this.
That I can store the information in a public class or struct and that I can
read this from every other form or class in my program.

Is there another way? And how can I do that?
thank you
Gerrit
 
Hi Gerrit,
In my application, the user must logon with a username and a password. In
all the tables in my database, there is a field user. By saving new or
changed records, the username is writed to that field.

You should think about normalizing your database by creating a Users table
and assigning a unique identifier (GUID or INT) to each user. Then, you can
add a foreign key constraint to each table where you want to keep track of
the user that performed the last modification. Instead of storing a name
you'd store the user's identifier in all of the related tables.

"Database Normalization"
http://en.wikipedia.org/wiki/Database_normalization
Now I have a class Session with the User-information.
By opening the program, I have code like this on the mainform:

Session sess = new Session().
sess.UserName = "John";

When I open a new form, then I do this:

frmNew frm = new frmNew(sess);

When I write to the Database, I do this:

Article art = new Article(sess);

etc.

This is working, but I was asking by myself, that maybe there must be
another way to do this.
That I can store the information in a public class or struct and that I
can read this from every other form or class in my program.

Is there another way? And how can I do that?

Yes, you can add a static member to your business object:

class User
{
private User currentUser;
public static User CurrentUser { get { return currentUser; } }

...
}

After you identify the user set the property, for example:

User user = new User("Gerrit");
User.CurrentUser = user;

And when you need to access it in another business object just read the
property:

class Article
{
public void Save()
{
User currentUser = User.CurrentUser;

...
}
}
 
The solution depends. One way you could solve this is by creating a
GenericIdentity and setting the current principal:
System.Security.Principal.IIdentity identity = new
System.Security.Principal.GenericIdentity("USERNAME");
System.Threading.Thread.CurrentPrincipal = new
System.Security.Principal.GenericPrincipal(identity, new string[0]);

Then anywhere in your code you can get the "USERNAME" as follows:
System.Threading.Thread.CurrentPrincipal.Identity.Name

If you are using SQL Server authentication you could let the database set
the user field with every insert, update ... using triggers.

Gabriel Lozano-Morán
 
Hi Gerrit,

Correction in my code sample:
public static User CurrentUser { get { return currentUser; } }

public static User CurrentUser {
get { return currentUser; }
set { currentUser = value; } // required for write-access
}
 
Gerrit,

I go for the answer from Gabriel, but just a little addition to your own
code. I would not use the name Session in this way. It is an attribute in
ASPNET what is almost a keyword.

Cor
 
Hi Cor,

I think a more OO approach is better. If the OP wants, there is no reason
why the User object can't just implement IIdentity as well, although I think

User.CurrentUser.Name

is much more legible than

System.Threading.Thread.CurrentPrincipal.Identity.Name

so I don't know why anyone would prefer the latter :)
 
Thank you all for the answers.

For now, the answer from Dave was where I was looking for, but I save the
others for later.

And I do not use the name Session in my application, but a dutch word
Sessie. I only translate it for my question here. thank you.

Gerrit.
 
Dave,

I agree with you that the CurrentPrincipal use is not the most logical.

I was more pointing on the inbuild security system.

Cor
 
Can someone please explain me why this is not the most logical solution? He
clearly says that the user has to logon. Is there any better solution than
to use a generic principal object?

Beside the fact that it violates the Law of Demeter I don't see what is
wrong with calling System.Threading.Thread.CurrentPrincipal.Identity.Name

Gabriel Lozano-Morán
 
Hi Gabriel,

Well it could be useful in certain circumstances, I was just suggesting that
an OO approach is much easier to use and understand.

Actually, I'm using that in a project I'm working on right now (although
I've implemented IIdentity in a strong-Typed DataRow). What I realized
after doing that is it was pointless. I ended up using my static Program
class to aggregate a bunch of static info for the runtime and I realized
that adding a CurrentUser property was much simpler, so I use
Program.CurrentUser in my app now. That's much nicer than
Thread.CurrentPrincipal.Identity.Name, don't you agree?
 
What you could do is create a static ApplicationContext class with a
CurrentUser property and then delegate the call to the
Thread.CurrentPrincipal.Identity

Gabriel Lozano-Morán

Dave Sexton said:
Hi Gabriel,

Well it could be useful in certain circumstances, I was just suggesting
that an OO approach is much easier to use and understand.

Actually, I'm using that in a project I'm working on right now (although
I've implemented IIdentity in a strong-Typed DataRow). What I realized
after doing that is it was pointless. I ended up using my static Program
class to aggregate a bunch of static info for the runtime and I realized
that adding a CurrentUser property was much simpler, so I use
Program.CurrentUser in my app now. That's much nicer than
Thread.CurrentPrincipal.Identity.Name, don't you agree?

--
Dave Sexton

Gabriel Lozano-Morán said:
Can someone please explain me why this is not the most logical solution?
He clearly says that the user has to logon. Is there any better solution
than to use a generic principal object?

Beside the fact that it violates the Law of Demeter I don't see what is
wrong with calling System.Threading.Thread.CurrentPrincipal.Identity.Name

Gabriel Lozano-Morán


Cor Ligthert said:
Dave,

I agree with you that the CurrentPrincipal use is not the most logical.

I was more pointing on the inbuild security system.

Cor

"Dave Sexton" <dave@jwa[remove.this]online.com> schreef in bericht
Hi Cor,

I think a more OO approach is better. If the OP wants, there is no
reason why the User object can't just implement IIdentity as well,
although I think

User.CurrentUser.Name

is much more legible than

System.Threading.Thread.CurrentPrincipal.Identity.Name

so I don't know why anyone would prefer the latter :)

--
Dave Sexton

Gerrit,

I go for the answer from Gabriel, but just a little addition to your
own code. I would not use the name Session in this way. It is an
attribute in ASPNET what is almost a keyword.

Cor

"Gerrit" <[email protected]> schreef in bericht
Hallo,

In my application, the user must logon with a username and a
password. In all the tables in my database, there is a field user. By
saving new or changed records, the username is writed to that field.

Now I have a class Session with the User-information.
By opening the program, I have code like this on the mainform:

Session sess = new Session().
sess.UserName = "John";

When I open a new form, then I do this:

frmNew frm = new frmNew(sess);

When I write to the Database, I do this:

Article art = new Article(sess);

etc.

This is working, but I was asking by myself, that maybe there must be
another way to do this.
That I can store the information in a public class or struct and that
I can read this from every other form or class in my program.

Is there another way? And how can I do that?
thank you
Gerrit
 
Hi Gabriel,

That's almost what I've done already, but what value does the Identity
property provide if I already have a business object?

My code looks like this (basically):

static class Program
{
// I'm using a strong-Typed DataRow (as I mentioned before)
public static ProgramData.UsersRow CurrentUser
{
get { return user; }
set { user = value; }
}

private static ProgramData.UsersRow user;
}

It doesn't get much simpler than that :)

The fact that ProgramData.UsersRow implements IIdentity and is assigned to
the current principal doesn't help me at all, although I've left that code
in place as well out of laziness.

--
Dave Sexton

Gabriel Lozano-Morán said:
What you could do is create a static ApplicationContext class with a
CurrentUser property and then delegate the call to the
Thread.CurrentPrincipal.Identity

Gabriel Lozano-Morán

Dave Sexton said:
Hi Gabriel,

Well it could be useful in certain circumstances, I was just suggesting
that an OO approach is much easier to use and understand.

Actually, I'm using that in a project I'm working on right now (although
I've implemented IIdentity in a strong-Typed DataRow). What I realized
after doing that is it was pointless. I ended up using my static Program
class to aggregate a bunch of static info for the runtime and I realized
that adding a CurrentUser property was much simpler, so I use
Program.CurrentUser in my app now. That's much nicer than
Thread.CurrentPrincipal.Identity.Name, don't you agree?

--
Dave Sexton

Gabriel Lozano-Morán said:
Can someone please explain me why this is not the most logical solution?
He clearly says that the user has to logon. Is there any better solution
than to use a generic principal object?

Beside the fact that it violates the Law of Demeter I don't see what is
wrong with calling
System.Threading.Thread.CurrentPrincipal.Identity.Name

Gabriel Lozano-Morán


Dave,

I agree with you that the CurrentPrincipal use is not the most logical.

I was more pointing on the inbuild security system.

Cor

"Dave Sexton" <dave@jwa[remove.this]online.com> schreef in bericht
Hi Cor,

I think a more OO approach is better. If the OP wants, there is no
reason why the User object can't just implement IIdentity as well,
although I think

User.CurrentUser.Name

is much more legible than

System.Threading.Thread.CurrentPrincipal.Identity.Name

so I don't know why anyone would prefer the latter :)

--
Dave Sexton

Gerrit,

I go for the answer from Gabriel, but just a little addition to your
own code. I would not use the name Session in this way. It is an
attribute in ASPNET what is almost a keyword.

Cor

"Gerrit" <[email protected]> schreef in bericht
Hallo,

In my application, the user must logon with a username and a
password. In all the tables in my database, there is a field user.
By saving new or changed records, the username is writed to that
field.

Now I have a class Session with the User-information.
By opening the program, I have code like this on the mainform:

Session sess = new Session().
sess.UserName = "John";

When I open a new form, then I do this:

frmNew frm = new frmNew(sess);

When I write to the Database, I do this:

Article art = new Article(sess);

etc.

This is working, but I was asking by myself, that maybe there must
be another way to do this.
That I can store the information in a public class or struct and
that I can read this from every other form or class in my program.

Is there another way? And how can I do that?
thank you
Gerrit
 
Garbriel,

I need in my eyes to much instructions using the principal that is all.
To much words for often done things, that is all.
(It should be done easier in my opinion, however that was again not about
your solution)

Cor
 
Hello Dave,

The added value is that you don't have to reinvent the wheel as the current
infrastructure (Base Class Library) already provides a mechanism to solve
your problem in the form of Principals and Identities. But as always there
is never only one good solution to a problem.

Gabriel Lozano-Morán
Hi Gabriel,

That's almost what I've done already, but what value does the Identity
property provide if I already have a business object?

My code looks like this (basically):

static class Program
{
// I'm using a strong-Typed DataRow (as I mentioned before)
public static ProgramData.UsersRow CurrentUser
{
get { return user; }
set { user = value; }
}
private static ProgramData.UsersRow user;
}
It doesn't get much simpler than that :)

The fact that ProgramData.UsersRow implements IIdentity and is
assigned to the current principal doesn't help me at all, although
I've left that code in place as well out of laziness.

What you could do is create a static ApplicationContext class with a
CurrentUser property and then delegate the call to the
Thread.CurrentPrincipal.Identity

Gabriel Lozano-Morán

Hi Gabriel,

Well it could be useful in certain circumstances, I was just
suggesting that an OO approach is much easier to use and understand.

Actually, I'm using that in a project I'm working on right now
(although I've implemented IIdentity in a strong-Typed DataRow).
What I realized after doing that is it was pointless. I ended up
using my static Program class to aggregate a bunch of static info
for the runtime and I realized that adding a CurrentUser property
was much simpler, so I use Program.CurrentUser in my app now.
That's much nicer than Thread.CurrentPrincipal.Identity.Name, don't
you agree?

-- Dave Sexton


Can someone please explain me why this is not the most logical
solution? He clearly says that the user has to logon. Is there any
better solution than to use a generic principal object?

Beside the fact that it violates the Law of Demeter I don't see
what is wrong with calling
System.Threading.Thread.CurrentPrincipal.Identity.Name

Gabriel Lozano-Morán


Dave,

I agree with you that the CurrentPrincipal use is not the most
logical.

I was more pointing on the inbuild security system.

Cor

"Dave Sexton" <dave@jwa[remove.this]online.com> schreef in bericht

Hi Cor,

I think a more OO approach is better. If the OP wants, there is
no reason why the User object can't just implement IIdentity as
well, although I think

User.CurrentUser.Name

is much more legible than

System.Threading.Thread.CurrentPrincipal.Identity.Name

so I don't know why anyone would prefer the latter :)

-- Dave Sexton


Gerrit,

I go for the answer from Gabriel, but just a little addition to
your own code. I would not use the name Session in this way. It
is an attribute in ASPNET what is almost a keyword.

Cor

"Gerrit" <[email protected]> schreef in bericht

Hallo,

In my application, the user must logon with a username and a
password. In all the tables in my database, there is a field
user. By saving new or changed records, the username is writed
to that field.

Now I have a class Session with the User-information. By
opening the program, I have code like this on the mainform:

Session sess = new Session().
sess.UserName = "John";
When I open a new form, then I do this:

frmNew frm = new frmNew(sess);

When I write to the Database, I do this:

Article art = new Article(sess);

etc.

This is working, but I was asking by myself, that maybe there
must
be another way to do this.
That I can store the information in a public class or struct
and
that I can read this from every other form or class in my
program.
Is there another way? And how can I do that?
thank you
Gerrit
 
Hi Gabriel,

It doesn't solve my problem. As you may recall, I tried your approach a
while back but realized soon that it wasn't enough and was more like I was
trying to use an FCL class just because it is an FCL class :)

The OP's User object will most likely add functionality that IIdentity
doesn't provide, such as CRUD operations or state such as a user's ID,
FirstName, LastName, etc - you know, the stuff most real-world applications
require, including the one I'm working on now. Implementing IIdentity and
using some abstract threading principal was just extra work for me. As I
already mentioned, it could be useful (e.g., if a third-party library uses
the currently logged on user's name for something), but within the context
of my own application it just doesn't provide any real value.

If some sort of roles framework is being used, as present in my current
project, then going through the principal is actually taking the long way to
get them. I'm using a custom DAL and DataSets (being partial in 2.0) are
perfect business entities for me. I've extended UsersRow with the following
code:

/// <summary>Gets a read-only copy of the user's roles.</summary>
public List<string> Roles
{
get
{
List<string> roles = new List<string>();

foreach (UserRolesRow role in GetUserRolesRows())
roles.Add(role.Role);

return roles;
}
}

My custom Users and Roles infrastructure allows me to do this:

Program.CurrentUser.Roles.Contains("admin");

and

Program.User.Roles.FindAll(delegate(string role) {
return role == "admin" || role == "manager";
});

--
Dave Sexton

Gabriel Lozano-Morán said:
Hello Dave,

The added value is that you don't have to reinvent the wheel as the
current infrastructure (Base Class Library) already provides a mechanism
to solve your problem in the form of Principals and Identities. But as
always there is never only one good solution to a problem.

Gabriel Lozano-Morán
Hi Gabriel,

That's almost what I've done already, but what value does the Identity
property provide if I already have a business object?

My code looks like this (basically):

static class Program
{
// I'm using a strong-Typed DataRow (as I mentioned before)
public static ProgramData.UsersRow CurrentUser
{
get { return user; }
set { user = value; }
}
private static ProgramData.UsersRow user;
}
It doesn't get much simpler than that :)

The fact that ProgramData.UsersRow implements IIdentity and is
assigned to the current principal doesn't help me at all, although
I've left that code in place as well out of laziness.

What you could do is create a static ApplicationContext class with a
CurrentUser property and then delegate the call to the
Thread.CurrentPrincipal.Identity

Gabriel Lozano-Morán


Hi Gabriel,

Well it could be useful in certain circumstances, I was just
suggesting that an OO approach is much easier to use and understand.

Actually, I'm using that in a project I'm working on right now
(although I've implemented IIdentity in a strong-Typed DataRow).
What I realized after doing that is it was pointless. I ended up
using my static Program class to aggregate a bunch of static info
for the runtime and I realized that adding a CurrentUser property
was much simpler, so I use Program.CurrentUser in my app now.
That's much nicer than Thread.CurrentPrincipal.Identity.Name, don't
you agree?

-- Dave Sexton


Can someone please explain me why this is not the most logical
solution? He clearly says that the user has to logon. Is there any
better solution than to use a generic principal object?

Beside the fact that it violates the Law of Demeter I don't see
what is wrong with calling
System.Threading.Thread.CurrentPrincipal.Identity.Name

Gabriel Lozano-Morán


Dave,

I agree with you that the CurrentPrincipal use is not the most
logical.

I was more pointing on the inbuild security system.

Cor

"Dave Sexton" <dave@jwa[remove.this]online.com> schreef in bericht

Hi Cor,

I think a more OO approach is better. If the OP wants, there is
no reason why the User object can't just implement IIdentity as
well, although I think

User.CurrentUser.Name

is much more legible than

System.Threading.Thread.CurrentPrincipal.Identity.Name

so I don't know why anyone would prefer the latter :)

-- Dave Sexton


Gerrit,

I go for the answer from Gabriel, but just a little addition to
your own code. I would not use the name Session in this way. It
is an attribute in ASPNET what is almost a keyword.

Cor

"Gerrit" <[email protected]> schreef in bericht

Hallo,

In my application, the user must logon with a username and a
password. In all the tables in my database, there is a field
user. By saving new or changed records, the username is writed
to that field.

Now I have a class Session with the User-information. By
opening the program, I have code like this on the mainform:

Session sess = new Session().
sess.UserName = "John";
When I open a new form, then I do this:

frmNew frm = new frmNew(sess);

When I write to the Database, I do this:

Article art = new Article(sess);

etc.

This is working, but I was asking by myself, that maybe there
must
be another way to do this.
That I can store the information in a public class or struct
and
that I can read this from every other form or class in my
program.
Is there another way? And how can I do that?
thank you
Gerrit
 
Hello Dave,

You could also create your own principal and identity objects and when you
need the principal object from the thread you can cast it to your custom
principal. So you could add the extra functionality to these classes and
in make the type of ApplicationContext.CurrentUser MyIdentity and then in
the getter write something like:

return (MyIdentity) Thread.CurrentPrincipal.Identity;

Gabriel Lozano-Morán
The .NET Aficionado
http://www.pointerx.net
Hi Gabriel,

It doesn't solve my problem. As you may recall, I tried your approach
a while back but realized soon that it wasn't enough and was more like
I was trying to use an FCL class just because it is an FCL class :)

The OP's User object will most likely add functionality that IIdentity
doesn't provide, such as CRUD operations or state such as a user's ID,
FirstName, LastName, etc - you know, the stuff most real-world
applications require, including the one I'm working on now.
Implementing IIdentity and using some abstract threading principal was
just extra work for me. As I already mentioned, it could be useful
(e.g., if a third-party library uses the currently logged on user's
name for something), but within the context of my own application it
just doesn't provide any real value.

If some sort of roles framework is being used, as present in my
current project, then going through the principal is actually taking
the long way to get them. I'm using a custom DAL and DataSets (being
partial in 2.0) are perfect business entities for me. I've extended
UsersRow with the following code:

/// <summary>Gets a read-only copy of the user's roles.</summary>
public List<string> Roles
{
get
{
List<string> roles = new List<string>();
foreach (UserRolesRow role in GetUserRolesRows())
roles.Add(role.Role);
return roles;
}
}
My custom Users and Roles infrastructure allows me to do this:

Program.CurrentUser.Roles.Contains("admin");

and

Program.User.Roles.FindAll(delegate(string role) {
return role == "admin" || role == "manager";
});
Hello Dave,

The added value is that you don't have to reinvent the wheel as the
current infrastructure (Base Class Library) already provides a
mechanism to solve your problem in the form of Principals and
Identities. But as always there is never only one good solution to a
problem.

Gabriel Lozano-Morán
Hi Gabriel,

That's almost what I've done already, but what value does the
Identity property provide if I already have a business object?

My code looks like this (basically):

static class Program
{
// I'm using a strong-Typed DataRow (as I mentioned before)
public static ProgramData.UsersRow CurrentUser
{
get { return user; }
set { user = value; }
}
private static ProgramData.UsersRow user;
}
It doesn't get much simpler than that :)
The fact that ProgramData.UsersRow implements IIdentity and is
assigned to the current principal doesn't help me at all, although
I've left that code in place as well out of laziness.


What you could do is create a static ApplicationContext class with
a CurrentUser property and then delegate the call to the
Thread.CurrentPrincipal.Identity

Gabriel Lozano-Morán


Hi Gabriel,

Well it could be useful in certain circumstances, I was just
suggesting that an OO approach is much easier to use and
understand.

Actually, I'm using that in a project I'm working on right now
(although I've implemented IIdentity in a strong-Typed DataRow).
What I realized after doing that is it was pointless. I ended up
using my static Program class to aggregate a bunch of static info
for the runtime and I realized that adding a CurrentUser property
was much simpler, so I use Program.CurrentUser in my app now.
That's much nicer than Thread.CurrentPrincipal.Identity.Name,
don't you agree?

-- Dave Sexton


Can someone please explain me why this is not the most logical
solution? He clearly says that the user has to logon. Is there
any better solution than to use a generic principal object?

Beside the fact that it violates the Law of Demeter I don't see
what is wrong with calling
System.Threading.Thread.CurrentPrincipal.Identity.Name

Gabriel Lozano-Morán


Dave,

I agree with you that the CurrentPrincipal use is not the most
logical.

I was more pointing on the inbuild security system.

Cor

"Dave Sexton" <dave@jwa[remove.this]online.com> schreef in
bericht
Hi Cor,

I think a more OO approach is better. If the OP wants, there
is no reason why the User object can't just implement IIdentity
as well, although I think

User.CurrentUser.Name

is much more legible than

System.Threading.Thread.CurrentPrincipal.Identity.Name

so I don't know why anyone would prefer the latter :)

-- Dave Sexton

message
Gerrit,

I go for the answer from Gabriel, but just a little addition
to your own code. I would not use the name Session in this
way. It is an attribute in ASPNET what is almost a keyword.

Cor

"Gerrit" <[email protected]> schreef in bericht

Hallo,

In my application, the user must logon with a username and a
password. In all the tables in my database, there is a field
user. By saving new or changed records, the username is
writed to that field.

Now I have a class Session with the User-information. By
opening the program, I have code like this on the mainform:

Session sess = new Session().
sess.UserName = "John";
When I open a new form, then I do this:
frmNew frm = new frmNew(sess);

When I write to the Database, I do this:

Article art = new Article(sess);

etc.

This is working, but I was asking by myself, that maybe there
must
be another way to do this.
That I can store the information in a public class or struct
and
that I can read this from every other form or class in my
program.
Is there another way? And how can I do that?
thank you
Gerrit
 
Hi Gabriel,

Correction:
Program.User.Roles.FindAll(delegate(string role) {
return role == "admin" || role == "manager";
});

The above should use Program.CurrentUser to remain consistent with my other
examples.

Actually, it's just Program.User in my real application (I copied and pasted
the code and changed the role literals) but I wanted it to be clear to the
OP so I used CurrentUser in my examples :)

--
Dave Sexton

Dave Sexton said:
Hi Gabriel,

It doesn't solve my problem. As you may recall, I tried your approach a
while back but realized soon that it wasn't enough and was more like I was
trying to use an FCL class just because it is an FCL class :)

The OP's User object will most likely add functionality that IIdentity
doesn't provide, such as CRUD operations or state such as a user's ID,
FirstName, LastName, etc - you know, the stuff most real-world
applications require, including the one I'm working on now. Implementing
IIdentity and using some abstract threading principal was just extra work
for me. As I already mentioned, it could be useful (e.g., if a
third-party library uses the currently logged on user's name for
something), but within the context of my own application it just doesn't
provide any real value.

If some sort of roles framework is being used, as present in my current
project, then going through the principal is actually taking the long way
to get them. I'm using a custom DAL and DataSets (being partial in 2.0)
are perfect business entities for me. I've extended UsersRow with the
following code:

/// <summary>Gets a read-only copy of the user's roles.</summary>
public List<string> Roles
{
get
{
List<string> roles = new List<string>();

foreach (UserRolesRow role in GetUserRolesRows())
roles.Add(role.Role);

return roles;
}
}

My custom Users and Roles infrastructure allows me to do this:

Program.CurrentUser.Roles.Contains("admin");

and

Program.User.Roles.FindAll(delegate(string role) {
return role == "admin" || role == "manager";
});

--
Dave Sexton

Gabriel Lozano-Morán said:
Hello Dave,

The added value is that you don't have to reinvent the wheel as the
current infrastructure (Base Class Library) already provides a mechanism
to solve your problem in the form of Principals and Identities. But as
always there is never only one good solution to a problem.

Gabriel Lozano-Morán
Hi Gabriel,

That's almost what I've done already, but what value does the Identity
property provide if I already have a business object?

My code looks like this (basically):

static class Program
{
// I'm using a strong-Typed DataRow (as I mentioned before)
public static ProgramData.UsersRow CurrentUser
{
get { return user; }
set { user = value; }
}
private static ProgramData.UsersRow user;
}
It doesn't get much simpler than that :)

The fact that ProgramData.UsersRow implements IIdentity and is
assigned to the current principal doesn't help me at all, although
I've left that code in place as well out of laziness.


What you could do is create a static ApplicationContext class with a
CurrentUser property and then delegate the call to the
Thread.CurrentPrincipal.Identity

Gabriel Lozano-Morán


Hi Gabriel,

Well it could be useful in certain circumstances, I was just
suggesting that an OO approach is much easier to use and understand.

Actually, I'm using that in a project I'm working on right now
(although I've implemented IIdentity in a strong-Typed DataRow).
What I realized after doing that is it was pointless. I ended up
using my static Program class to aggregate a bunch of static info
for the runtime and I realized that adding a CurrentUser property
was much simpler, so I use Program.CurrentUser in my app now.
That's much nicer than Thread.CurrentPrincipal.Identity.Name, don't
you agree?

-- Dave Sexton


Can someone please explain me why this is not the most logical
solution? He clearly says that the user has to logon. Is there any
better solution than to use a generic principal object?

Beside the fact that it violates the Law of Demeter I don't see
what is wrong with calling
System.Threading.Thread.CurrentPrincipal.Identity.Name

Gabriel Lozano-Morán


Dave,

I agree with you that the CurrentPrincipal use is not the most
logical.

I was more pointing on the inbuild security system.

Cor

"Dave Sexton" <dave@jwa[remove.this]online.com> schreef in bericht

Hi Cor,

I think a more OO approach is better. If the OP wants, there is
no reason why the User object can't just implement IIdentity as
well, although I think

User.CurrentUser.Name

is much more legible than

System.Threading.Thread.CurrentPrincipal.Identity.Name

so I don't know why anyone would prefer the latter :)

-- Dave Sexton


Gerrit,

I go for the answer from Gabriel, but just a little addition to
your own code. I would not use the name Session in this way. It
is an attribute in ASPNET what is almost a keyword.

Cor

"Gerrit" <[email protected]> schreef in bericht

Hallo,

In my application, the user must logon with a username and a
password. In all the tables in my database, there is a field
user. By saving new or changed records, the username is writed
to that field.

Now I have a class Session with the User-information. By
opening the program, I have code like this on the mainform:

Session sess = new Session().
sess.UserName = "John";
When I open a new form, then I do this:

frmNew frm = new frmNew(sess);

When I write to the Database, I do this:

Article art = new Article(sess);

etc.

This is working, but I was asking by myself, that maybe there
must
be another way to do this.
That I can store the information in a public class or struct
and
that I can read this from every other form or class in my
program.
Is there another way? And how can I do that?
thank you
Gerrit
 
Hi Gabriel,
You could also create your own principal and identity objects and when you
need the principal object from the thread you can cast it to your custom
principal. So you could add the extra functionality to these classes and
in make the type of ApplicationContext.CurrentUser MyIdentity and then in
the getter write something like:

return (MyIdentity) Thread.CurrentPrincipal.Identity;

Well, I could, but there is no need to do that, nor will it provide anything
useful over my current solution where I simply return "user".

BTW, I prefer using the Program class - I'm not looking for another solution
here - I'm using a custom framework that I wrote named, "AppBase", and my
Program class actually derives from a base class named,
"ApplicationManager", so it's not actually static. My infrastructure is
already in place and has been working nicely for me for about 2 years now,
and there has never been a need or desire to use a thread principal at all
since I switched to using a simple static field.

I prefer my code simply because it's more legible, doesn't require any
interface implementation, doesn't require using a BCL infrastructure under
my custom business objects anyway, and it's really easy to understand.

It looks like we're just going to have to disagree on this :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top