By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
437,708 Members | 2,095 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 437,708 IT Pros & Developers. It's quick & easy.

Architecture Q - BLL for Web UI and Forms UI

P: n/a
Hello,

I have a class library of business objects that will accessed both by an
ASP.Net front end and a WinForms front-end. A typical business object in
class library, let's say "Employee", has a save method. In the save method,
after the employee record is successfully saved, a record is created in the
history table to record who saved the object when. The user name, IP address
(if it's web), and other information I would like to add to have in the
history record are already in the ASP.Net session, but I don't want my BLL
to be dependent on the HTTPContext object. I'd like to avoid having to pass
all this info as parameters to the Employee.Save method (or Delete and
Create methods for that matter), and I'd like to be able to use the object
from either the web or form UI. I thought about setting the fields in a
shared class, which would be fine for the Forms UI but wouldn't work (I
don't believe) for the Web UI because each user would over-write the
user-specific info in the shared class. Does anyone have any ideas for this?
TIA,

Monty
Apr 16 '07 #1
Share this Question
Share on Google+
11 Replies


P: n/a

I suggest a Factory approach.

You create a custom object to store info. Actually, Id create an interface
and an implementation.

Then you create a factory to return an object (or an implementation of that
interface) based on whether you're in a winforms or web environment.

Check out my blog here:
12/1/2005
Understanding the Simple Factory Pattern
http://sholliday.spaces.live.com/blog/

and you care about "Factory By Environment"
Somewhere, you're gonna have to reference System.Web
If that's your cruz, then pick wisely. If you don't want you biz layer to
reference it, then you'll have to put it in its own assembly.

In this rare care, I actually do let the biz layer reference the System.Web
namespace/dll, knowing I don't use it anywhere else.

But there's an idea for you.

"Monty" <mo***@community.nospamwrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl...
Hello,

I have a class library of business objects that will accessed both by an
ASP.Net front end and a WinForms front-end. A typical business object in
class library, let's say "Employee", has a save method. In the save
method,
after the employee record is successfully saved, a record is created in
the
history table to record who saved the object when. The user name, IP
address
(if it's web), and other information I would like to add to have in the
history record are already in the ASP.Net session, but I don't want my BLL
to be dependent on the HTTPContext object. I'd like to avoid having to
pass
all this info as parameters to the Employee.Save method (or Delete and
Create methods for that matter), and I'd like to be able to use the object
from either the web or form UI. I thought about setting the fields in a
shared class, which would be fine for the Forms UI but wouldn't work (I
don't believe) for the Web UI because each user would over-write the
user-specific info in the shared class. Does anyone have any ideas for
this?
TIA,

Monty


Apr 16 '07 #2

P: n/a
Hi Sloan (Ferris Bueller theme starts playing in the back of my brain),

Thanks for the demo, I think I will use that method. I'm not a native C#
user but I think I was able to figure everything out. I'm wondering why you
went through the trouble to create two different holder classes, an
IObjectHolder interface, and an ObjectHolderFactory when it seems it could
all be rolled into one pretty easily. I did this (below) and it seems to be
working (just from a very basic/quick test). Am I missing something obvious?

Public Class UserInfo
Private Shared singletonInstance As UserInfo
Private Shared ReadOnly SESSION_OBJECT_GUID As String =
"123503F8-6CBD-46F0-ACDC-98683A94360C"
Private _UserName As String = ""
Private _UserID As String = ""
Private _WorkstationID As String = ""

Private Sub New() 'a private constructor keeps anyone else from
creating this
End Sub

Public Shared Function GetInstance() As UserInfo
If singletonInstance Is Nothing Then
If System.Web.HttpContext.Current Is Nothing Then 'windows forms
environment:
singletonInstance = New UserInfo
Else 'web environment:
If System.Web.HttpContext.Current.Session IsNot Nothing Then
If
System.Web.HttpContext.Current.Session(SESSION_OBJ ECT_GUID) IsNot Nothing
Then
singletonInstance =
TryCast(System.Web.HttpContext.Current.Session(SES SION_OBJECT_GUID),
UserInfo)
Else
singletonInstance = New UserInfo
System.Web.HttpContext.Current.Session(SESSION_OBJ ECT_GUID)
= singletonInstance
End If
End If
End If
End If
Return singletonInstance
End Function

Public Property UserID() As String
Get
Return _UserID
End Get
Set(ByVal value As String)
_UserID = value
End Set
End Property
Public Property UserName() As String
Get
Return _UserName
End Get
Set(ByVal value As String)
_UserName = value
End Set
End Property
Public Property WorkstationID() As String
Get
Return _WorkstationID
End Get
Set(ByVal value As String)
_WorkstationID = value
End Set
End Property
End Class

I could also add a Dispose method to clean up, of course.

Thanks again.
Apr 16 '07 #3

P: n/a
I revised that GetInstance a bit (to make sure we're getting it from the
session when we're in the web scenario):
Public Shared Function GetInstance() As UserInfo
If System.Web.HttpContext.Current Is Nothing Then 'windows forms
environment:
If singletonInstance Is Nothing Then singletonInstance = New
UserInfo
Return singletonInstance
Else 'web environment:
If System.Web.HttpContext.Current.Session IsNot Nothing Then
If
System.Web.HttpContext.Current.Session(SESSION_OBJ ECT_GUID) Is Nothing Then
System.Web.HttpContext.Current.Session(SESSION_OBJ ECT_GUID)
= New UserInfo
End If
Return
TryCast(System.Web.HttpContext.Current.Session(SES SION_OBJECT_GUID),
UserInfo)
Else
Return Nothing 'Throw exception?
End If
End If
End Function
Apr 16 '07 #4

P: n/a

create two different holder classes, an
IObjectHolder interface, and an ObjectHolderFactory when it seems it could
all be rolled into one pretty easily
Because one should program to an interface, not an implementation.
Google the phrase
"to an interface" and "not an implementation"

I think what I had in mind was something like this

I'll try to vb.net improvise
public IUserInfo as interface
readonly property UserName as string
readonly property UserID as string
readonly property IPAddress as string
public class WinformsUserInfo : implements IUserInfo

public sub new
'here is where you figure out the winforms info you want to give
back..... set some member variables which you later expose as properties
end sub

UserName '' return the windows identity
UserID ''
IPAddress '' (return string.Empty since you weren't interested in this

public class WebUserInfo : implements IUserInfo

public sub new
'here is where you figure out the webform info you want to give
back..... set some member variables which you later expose as properties
end sub

UserName '' return ... Membership or whatever you keep as the UserName
in the web environment
UserID ''
IPAddress '' return the ... what is it? the Server object like
Server(REMOTE_IP_ADDRESS)
now you have 2 classes, both implement IUserInfo


' Here is your "factory"

Public Class UserInfoFactory

Private Sub New()
End Sub 'New
Public Shared Function GetUserInfo() As IUserInfo

If Nothing = System.Web.HttpContext.Current Then ' Add a reference to
System.Web.dll
'Non Web Environment
return new WinformsUserInfo
Else 'Web Environment
Return new WebUserInfo
End If
End Function
End Class

If you put that code in the biz layer, then it doesn't matter if you're in
the web or winforms environment, because the factory decides for you.
All you care about it getting ~a implementation of IUserInfo ... you don't
care which one.
What you did is create a single web version of the UserInfo class.
This isn't what you want.
I'd start over using the guide lines above.
DO NOT DO THIS............
Public Class UserInfo

public readonly property IPAddress as string

get
If Nothing = System.Web.HttpContext.Current Then ' Add a reference to
System.Web.dll
return "IPAddress not available in winforms"

Else 'Web Environment
Return Server(REMOTE_IP_ADDRESS)
End If

end get

end property
That's a whole lot of big nasty hack.
If you don't have alot of experience with Design Patterns, I'd go here
http://www.dofactory.com/Patterns/PatternFactory.aspx

and try a few out.

The power of design patterns is not knowing them, its knowing where to apply
them.
There are tons of articles about them on the web.
And design patterns are "above" any language.
I can talk to a java guy about a software solution, and we can talk about
how to use design patterns to solve it.
We don't care that I program in C# and he in java.

The above is your first lesson, I would try to learn more.
It'll get you on the road to what real OO is about.

..Good luck.


"Monty" <mo***@community.nospamwrote in message
news:Oh**************@TK2MSFTNGP06.phx.gbl...
Hi Sloan (Ferris Bueller theme starts playing in the back of my brain),

Thanks for the demo, I think I will use that method. I'm not a native C#
user but I think I was able to figure everything out. I'm wondering why
you
went through the trouble to create two different holder classes, an
IObjectHolder interface, and an ObjectHolderFactory when it seems it could
all be rolled into one pretty easily. I did this (below) and it seems to
be
working (just from a very basic/quick test). Am I missing something
obvious?
>
Public Class UserInfo
Private Shared singletonInstance As UserInfo
Private Shared ReadOnly SESSION_OBJECT_GUID As String =
"123503F8-6CBD-46F0-ACDC-98683A94360C"
Private _UserName As String = ""
Private _UserID As String = ""
Private _WorkstationID As String = ""

Private Sub New() 'a private constructor keeps anyone else from
creating this
End Sub

Public Shared Function GetInstance() As UserInfo
If singletonInstance Is Nothing Then
If System.Web.HttpContext.Current Is Nothing Then 'windows
forms
environment:
singletonInstance = New UserInfo
Else 'web environment:
If System.Web.HttpContext.Current.Session IsNot Nothing
Then
If
System.Web.HttpContext.Current.Session(SESSION_OBJ ECT_GUID) IsNot Nothing
Then
singletonInstance =
TryCast(System.Web.HttpContext.Current.Session(SES SION_OBJECT_GUID),
UserInfo)
Else
singletonInstance = New UserInfo
System.Web.HttpContext.Current.Session(SESSION_OBJ ECT_GUID)
= singletonInstance
End If
End If
End If
End If
Return singletonInstance
End Function

Public Property UserID() As String
Get
Return _UserID
End Get
Set(ByVal value As String)
_UserID = value
End Set
End Property
Public Property UserName() As String
Get
Return _UserName
End Get
Set(ByVal value As String)
_UserName = value
End Set
End Property
Public Property WorkstationID() As String
Get
Return _WorkstationID
End Get
Set(ByVal value As String)
_WorkstationID = value
End Set
End Property
End Class

I could also add a Dispose method to clean up, of course.

Thanks again.


Apr 16 '07 #5

P: n/a

PS

Your factory ~can return an abstract class also
public mustinherit class UserInfo

property UserName as string '' we'll actually handle username here in
this class

public MustOverride Property IPAddress as string '' we let the concrete
classes handle this property


public class WebUserInfo : inherits UserInfo

public readonly property IPAddress as string
get
return Server(REMOTE_IP_ADDRESS)
end get
end property

end class
public class WinformsUserInfo : inherits UserInfo
public readonly property IPAddress as string
get
return string.Empty
end get
end property

end class

Your factory will return a UserInfo
and you'll still just pass back 1 or the 2 objects, based on that Nothing
check on the CurrentSession object.

Notice you don't have a bunch of "If" statements in the code saying what
the IP address is.
Each concrete class takes care of its own business.
While this is a simple situation you have, I'd actually spend a good amount
of time exploring it, and the factory approach.
If you can get this concept to "click", you start down a road of less
hacking, and more OO code.
But you gotta work through it, and figure out what is happening.
If you have biz logic with many many
"if this else this that the other"
lines... you can simplify your code by using factories.
The key of course (as stated at the very beginning) is that one should
"Code to an Interface, not an implementation"
...


"sloan" <sl***@ipass.netwrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl...
>
create two different holder classes, an
IObjectHolder interface, and an ObjectHolderFactory when it seems it could
all be rolled into one pretty easily
Because one should program to an interface, not an implementation.
Google the phrase
"to an interface" and "not an implementation"

I think what I had in mind was something like this

I'll try to vb.net improvise
public IUserInfo as interface
readonly property UserName as string
readonly property UserID as string
readonly property IPAddress as string
public class WinformsUserInfo : implements IUserInfo

public sub new
'here is where you figure out the winforms info you want to give
back..... set some member variables which you later expose as properties
end sub

UserName '' return the windows identity
UserID ''
IPAddress '' (return string.Empty since you weren't interested in this

public class WebUserInfo : implements IUserInfo

public sub new
'here is where you figure out the webform info you want to give
back..... set some member variables which you later expose as properties
end sub

UserName '' return ... Membership or whatever you keep as the UserName
in the web environment
UserID ''
IPAddress '' return the ... what is it? the Server object like
Server(REMOTE_IP_ADDRESS)
now you have 2 classes, both implement IUserInfo


' Here is your "factory"

Public Class UserInfoFactory

Private Sub New()
End Sub 'New
Public Shared Function GetUserInfo() As IUserInfo

If Nothing = System.Web.HttpContext.Current Then ' Add a reference
to
System.Web.dll
'Non Web Environment
return new WinformsUserInfo
Else 'Web Environment
Return new WebUserInfo
End If
End Function
End Class

If you put that code in the biz layer, then it doesn't matter if you're in
the web or winforms environment, because the factory decides for you.
All you care about it getting ~a implementation of IUserInfo ... you don't
care which one.
What you did is create a single web version of the UserInfo class.
This isn't what you want.
I'd start over using the guide lines above.
DO NOT DO THIS............
Public Class UserInfo

public readonly property IPAddress as string

get
If Nothing = System.Web.HttpContext.Current Then ' Add a reference
to
System.Web.dll
return "IPAddress not available in winforms"

Else 'Web Environment
Return Server(REMOTE_IP_ADDRESS)
End If

end get

end property
That's a whole lot of big nasty hack.
If you don't have alot of experience with Design Patterns, I'd go here
http://www.dofactory.com/Patterns/PatternFactory.aspx

and try a few out.

The power of design patterns is not knowing them, its knowing where to
apply
them.
There are tons of articles about them on the web.
And design patterns are "above" any language.
I can talk to a java guy about a software solution, and we can talk about
how to use design patterns to solve it.
We don't care that I program in C# and he in java.

The above is your first lesson, I would try to learn more.
It'll get you on the road to what real OO is about.

.Good luck.


"Monty" <mo***@community.nospamwrote in message
news:Oh**************@TK2MSFTNGP06.phx.gbl...
Hi Sloan (Ferris Bueller theme starts playing in the back of my brain),

Thanks for the demo, I think I will use that method. I'm not a native C#
user but I think I was able to figure everything out. I'm wondering why
you
went through the trouble to create two different holder classes, an
IObjectHolder interface, and an ObjectHolderFactory when it seems it
could
all be rolled into one pretty easily. I did this (below) and it seems to
be
working (just from a very basic/quick test). Am I missing something
obvious?

Public Class UserInfo
Private Shared singletonInstance As UserInfo
Private Shared ReadOnly SESSION_OBJECT_GUID As String =
"123503F8-6CBD-46F0-ACDC-98683A94360C"
Private _UserName As String = ""
Private _UserID As String = ""
Private _WorkstationID As String = ""

Private Sub New() 'a private constructor keeps anyone else from
creating this
End Sub

Public Shared Function GetInstance() As UserInfo
If singletonInstance Is Nothing Then
If System.Web.HttpContext.Current Is Nothing Then 'windows
forms
environment:
singletonInstance = New UserInfo
Else 'web environment:
If System.Web.HttpContext.Current.Session IsNot Nothing
Then
If
System.Web.HttpContext.Current.Session(SESSION_OBJ ECT_GUID) IsNot
Nothing
Then
singletonInstance =
TryCast(System.Web.HttpContext.Current.Session(SES SION_OBJECT_GUID),
UserInfo)
Else
singletonInstance = New UserInfo
System.Web.HttpContext.Current.Session(SESSION_OBJ ECT_GUID)
= singletonInstance
End If
End If
End If
End If
Return singletonInstance
End Function

Public Property UserID() As String
Get
Return _UserID
End Get
Set(ByVal value As String)
_UserID = value
End Set
End Property
Public Property UserName() As String
Get
Return _UserName
End Get
Set(ByVal value As String)
_UserName = value
End Set
End Property
Public Property WorkstationID() As String
Get
Return _WorkstationID
End Get
Set(ByVal value As String)
_WorkstationID = value
End Set
End Property
End Class

I could also add a Dispose method to clean up, of course.

Thanks again.


Apr 16 '07 #6

P: n/a
Hi Sloan,

I am familiar with interface-based programming but, as you guessed, not up
on design patterns. I will research it more (though Rocky's VB 2005 BO book
is next in the queue), but in defiance of the sound principal "It's better
be quiet and be thought a fool than to open your mouth and prove it", my
initial impression on the difference between our two implementations (your
elegant one and my "whole lot of big nasty hack") is that after about the
3rd or 4th time that I had change something in ~both~ WebSessionObjectHolder
and InMemoryObjectHolder the honeymoon would be over. I am attracted to the
fact that my "hack" encapsulates all it's functionality into single, easily
maintainable class (as opposed to spread out between three classes and an
interface), does not duplicate the exact same properties and methods in two
different places, does not require a helper class and does not add four
files to my solution to maintain. In your implementation, since there will
never be more than two concrete classes that do 99% the same thing except
store themselves a little differently, is it worth all the overhead?

OK, I'm reading your posts again and wonder if you misunderstood my
implementation. You said:

=======================
DO NOT DO THIS............

Public Class UserInfo
public readonly property IPAddress as string
get
If Nothing = System.Web.HttpContext.Current Then
return "IPAddress not available in winforms"
Else 'Web Environment
Return Server(REMOTE_IP_ADDRESS)
End If
end get
end property

That's a whole lot of big nasty hack.
=======================

And in the next email you said:

=======================
Your factory will return a UserInfo
and you'll still just pass back 1 or the 2 objects, based on that
Nothing check on the CurrentSession object.

Notice you don't have a bunch of "If" statements in the code
saying what the IP address is. Each concrete class takes
care of its own business.
=======================

By my prototype doesn't do that at all. The only branching (between WebUI vs
WinForms) is in the GetInstance method, there is no branching in the
properties. Any relevant user info is stashed in the UserInfo object when
the user logs in (whether it be via web or windows), so there is no need for
the UserInfo class to reach out to the Server object to get the IP address
if it's in one environment or do something else if it's in another.
Regarding "Each concrete class takes care of its own business", the
"business" is 100% the same, with the only exception of how GetInstance does
it's magic depending on the environment.

Anyway, I will read up on patterns and perhaps I will see the error of my
ways. Thanks again for the sample app and blog post, it was very helpful.
Apr 16 '07 #7

P: n/a
Hi Monty,

Yes, I agree that if you want to put the code for both FormUI and ASP.NET
web application together in the same component class, you should use the
(HttpContext.Current == null) to detect and separate the code path. For
FormUI part, you can use a shared static class members while for ASP.NET,
you can use Session State or other per-user specific storage.
Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead
This posting is provided "AS IS" with no warranties, and confers no rights.

Apr 16 '07 #8

P: n/a

Ok.

Let me rephrase something.

When I say "big nasty hack", what I mean is that you don't want "if"
conditions in your UserInfo class based on the CurrentSession being
null/nothing or not.
Why?
Because every time you have a different property, you may have to add that
if statement to it.
Aka, if you have 100 properties, you would have 100 if checks about the
CurrentSession

That's where you code becomes non maintainable.


I think the cleanest solution is this.

Code up your UserInfo object.
Code it up so that it the properties are "dumb" in that you just put in
strings and bools and ints in it.
Make UserInfo serializable.

Create a UserInfoFactory class.

public class UserInfoFactory
private sub new
end sub

public shared function GetUserInfoBasedOnEnvironment as UserInfo

' use the CurrentSession check here
'populate properties of UserInfo based on whether you're in the web
or not
'at least with this approach you have encapsulated in ONE place where
all the if logic is.

'the main point im trying to make is DO NOT code up multiple "if"
statements in the UserInfo class itself.
end function

end class
I understand your concerns. And you're right about the duplication of
effort for the properties.
It looks like you just want to be able to "find the person who is doing the
action" whenever you need that info for a .Save operation.
So here is a little Employee.Save mockup
public class EmployeeController

public sub new
end sub

public sub SaveEmployee ( e as Employee ) 'notice the signature doesn't
have userInfo in it

dim ui as UserInfo
ui = UserInfoFactory.GetUserInfoBasedOnEnvironment()
dim dataLayerObject as EmployeeData
dataLayerObject = new EmployeeData
dataLayerObject.Save ( e.SSN, e. LastName, e.FirstName ,
u.UserID )

return

end sub

end class

Maybe that looks a little better.

I know you're getting flooded with info, but I would also read

6/5/2006
Custom Objects and Tiered Development II // 2.0
at my blog site (or the may 2006 version for 1.1)
If you still have questions, then maybe go back and reedit your original
post.
................

Just to add , the purpose of the
IObjectHolder

was not to be a template for creating other classes like that.

Its purpose was to give you a place to persist an object into memory,
WITHOUT having to write different code for asp.net or winforms.

I think you'd find it useful. Again, it would be for persisting an object
you've already got a hold of.
Lets say you find out that the
GetUserInfoBasedOnEnvironment

takes 10 minutes to run (in a winforms enviroment maybe) (this is all just
speculation to show a point) and generate a UserInfo object because it has
to check ActiveDirectory, and you're AD is slow.

So you decide "Man, I need that info, but its so slow I only want to that
price one time".

So you want to persist that object somewhere.

So in asp.net you say "I'll put it in the Session", And in winforms you say
"I'll throw into into memory as a singleton".

And you start coding away. And boom, you've got Session and winforms code
scattered out everywhere, aka, not easy to maintain.
Here is the method I would use ( talking about my blog)

''---------------------------------------------- abc
dim ui as UserInfo (code from above)

dim ioh as IObjectHolder
ioh = ObjectHolder.GetObjectHolder() '' it doesn't care whether or not I'm
in the web or winforms environment, the factory takes care of that for me

ioh.Add ( "SOMEKEY" , ui )

..............

Now its in the cache, and when I need it.
dim ui as UserInfo
ui = ObjectHolder.GetObjectHolder().Item("SOMEKEY")
if (not (ui is nothing) ) then
'I got the ui from the cache !!
end if

''---------------------------------def

You see the code between -------abc and -------------def

You put that in your biz layer AND ITS THE SAME CODE WHETHER YOURE IN
Asp.net Or winforms.
that's the beauty of the Factory. you're code on teh outside world becomes
cleaner.
because you're only got 1 "currentsession is nothing" check ( or 2 if you
count the other factory method)

That's what I mean by hacky code. When you can avoid writing the same "if"
statment all over the place, and have it in one place, and simplify your
code because you don't have intermixed asp.net and winforms code every AND
get reuse by pushing it into the biz layer, you're gaining significant
maintenance abilities.
I'll close with this.

The cost of software development is NOT the development time.
Its the maintenance costs.

So its fine to say "hmmm that doesn't look right". But at the same time
give it a serious try.
The argument "I'd have to add an extra class or extra interface" is not a
good one most times.

The design patterns give you the template for how to approach a common
problem. And sometimes you code up some extra files.
But the maintenance will be easier down the road.
Good luck. I think' you've hit some new concepts today!




"Monty" <mo***@community.nospamwrote in message
news:ua****************@TK2MSFTNGP04.phx.gbl...
Hi Sloan,

I am familiar with interface-based programming but, as you guessed, not up
on design patterns. I will research it more (though Rocky's VB 2005 BO
book
is next in the queue), but in defiance of the sound principal "It's better
be quiet and be thought a fool than to open your mouth and prove it", my
initial impression on the difference between our two implementations (your
elegant one and my "whole lot of big nasty hack") is that after about the
3rd or 4th time that I had change something in ~both~
WebSessionObjectHolder
and InMemoryObjectHolder the honeymoon would be over. I am attracted to
the
fact that my "hack" encapsulates all it's functionality into single,
easily
maintainable class (as opposed to spread out between three classes and an
interface), does not duplicate the exact same properties and methods in
two
different places, does not require a helper class and does not add four
files to my solution to maintain. In your implementation, since there will
never be more than two concrete classes that do 99% the same thing except
store themselves a little differently, is it worth all the overhead?

OK, I'm reading your posts again and wonder if you misunderstood my
implementation. You said:

=======================
DO NOT DO THIS............

Public Class UserInfo
public readonly property IPAddress as string
get
If Nothing = System.Web.HttpContext.Current Then
return "IPAddress not available in winforms"
Else 'Web Environment
Return Server(REMOTE_IP_ADDRESS)
End If
end get
end property

That's a whole lot of big nasty hack.
=======================

And in the next email you said:

=======================
Your factory will return a UserInfo
and you'll still just pass back 1 or the 2 objects, based on that
Nothing check on the CurrentSession object.

Notice you don't have a bunch of "If" statements in the code
saying what the IP address is. Each concrete class takes
care of its own business.
=======================

By my prototype doesn't do that at all. The only branching (between WebUI
vs
WinForms) is in the GetInstance method, there is no branching in the
properties. Any relevant user info is stashed in the UserInfo object when
the user logs in (whether it be via web or windows), so there is no need
for
the UserInfo class to reach out to the Server object to get the IP address
if it's in one environment or do something else if it's in another.
Regarding "Each concrete class takes care of its own business", the
"business" is 100% the same, with the only exception of how GetInstance
does
it's magic depending on the environment.

Anyway, I will read up on patterns and perhaps I will see the error of my
ways. Thanks again for the sample app and blog post, it was very helpful.


Apr 16 '07 #9

P: n/a
Thanks Sloan, I really do appreciate your time. I'm pickin up what you're
puttin down, but I'm not sure that I've explained myself well. You said:
Why?
Because every time you have a different property, you may have to add that
if statement to it.
Aka, if you have 100 properties, you would have 100 if checks about the
CurrentSession
but if you look at my code (in my second post) and read my last post, you
should see that:
my prototype doesn't do that at all. The ~only~ branching (between WebUI
vs WinForms) is in the GetInstance method, there is no branching in the
properties. Any relevant user info is stashed in the UserInfo object when
the user logs in (whether it be via web or windows), so there is no need
for
the UserInfo class to reach out to the Server object to get the IP address
if it's in one environment or do something else if it's in another.
The only thing I don't understand is why you'd want a separate factory
object in this case, once given that there is only going to be one of these
classes ("UserInfo"). You said that this code is less hacky:
dim ui as UserInfo
ui = UserInfoFactory.GetUserInfoBasedOnEnvironment()
dim dataLayerObject as EmployeeData
dataLayerObject = new EmployeeData
dataLayerObject.Save (e.SSN, e. LastName, e.FirstName, _
u.UserID)
But with the creation method ("GetInstance") encapsulated in the object
itself my code would look like this:

dim dataLayerObject as EmployeeData
dataLayerObject = new EmployeeData
dataLayerObject.Save (e.SSN, e. LastName, e.FirstName, _
UserInfo.GetInstance.UserID)

Anyway, there is no need to reply if you don't like, you've certainly paid
your dues on this topic ;-). I thank you again for your time and your sample
code, it's been very helpful.
Apr 16 '07 #10

P: n/a

I think you want a UserInfo singleton.

But because you're in a hybrid environment, aspnet and winforms
picking how to implement that singleton is the issue.

I think you're clued into what's going on.
So take what I said with a grain of salt. Obviously, if we were sitting
next to each other at a comptuer, we could figure it out faster.

But I think you have the tools and warnings now.

Good luck.
dataLayerObject.Save (e.SSN, e. LastName, e.FirstName, _
UserInfo.GetInstance.UserID)

That's definately a UserInfo singleton syntax. Which is fine.
Sometimes I code out the objects just to make it clear what is going on.
The above syntax would be correct, the key being you made the UserInfo
singleton work in both environments.


"Monty" <mo***@community.nospamwrote in message
news:%2***************@TK2MSFTNGP05.phx.gbl...
Thanks Sloan, I really do appreciate your time. I'm pickin up what you're
puttin down, but I'm not sure that I've explained myself well. You said:
Why?
Because every time you have a different property, you may have to add
that
if statement to it.
Aka, if you have 100 properties, you would have 100 if checks about the
CurrentSession

but if you look at my code (in my second post) and read my last post, you
should see that:
my prototype doesn't do that at all. The ~only~ branching (between WebUI
vs WinForms) is in the GetInstance method, there is no branching in the
properties. Any relevant user info is stashed in the UserInfo object
when
the user logs in (whether it be via web or windows), so there is no need
for
the UserInfo class to reach out to the Server object to get the IP
address
if it's in one environment or do something else if it's in another.

The only thing I don't understand is why you'd want a separate factory
object in this case, once given that there is only going to be one of
these
classes ("UserInfo"). You said that this code is less hacky:
dim ui as UserInfo
ui = UserInfoFactory.GetUserInfoBasedOnEnvironment()
dim dataLayerObject as EmployeeData
dataLayerObject = new EmployeeData
dataLayerObject.Save (e.SSN, e. LastName, e.FirstName, _
u.UserID)

But with the creation method ("GetInstance") encapsulated in the object
itself my code would look like this:

dim dataLayerObject as EmployeeData
dataLayerObject = new EmployeeData
dataLayerObject.Save (e.SSN, e. LastName, e.FirstName, _
UserInfo.GetInstance.UserID)

Anyway, there is no need to reply if you don't like, you've certainly paid
your dues on this topic ;-). I thank you again for your time and your
sample
code, it's been very helpful.


Apr 16 '07 #11

P: n/a
Thanks Sloan, I've added your blog to my watch list. Love the granada, BTW!
Apr 17 '07 #12

This discussion thread is closed

Replies have been disabled for this discussion.