473,806 Members | 2,771 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Architecture Q - BLL for Web UI and Forms UI

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
11 1944

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***@communit y.nospamwrote in message
news:%2******** ********@TK2MSF TNGP02.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
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 ObjectHolderFac tory 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 singletonInstan ce 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 singletonInstan ce Is Nothing Then
If System.Web.Http Context.Current Is Nothing Then 'windows forms
environment:
singletonInstan ce = New UserInfo
Else 'web environment:
If System.Web.Http Context.Current .Session IsNot Nothing Then
If
System.Web.Http Context.Current .Session(SESSIO N_OBJECT_GUID) IsNot Nothing
Then
singletonInstan ce =
TryCast(System. Web.HttpContext .Current.Sessio n(SESSION_OBJEC T_GUID),
UserInfo)
Else
singletonInstan ce = New UserInfo
System.Web.Http Context.Current .Session(SESSIO N_OBJECT_GUID)
= singletonInstan ce
End If
End If
End If
End If
Return singletonInstan ce
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
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.Http Context.Current Is Nothing Then 'windows forms
environment:
If singletonInstan ce Is Nothing Then singletonInstan ce = New
UserInfo
Return singletonInstan ce
Else 'web environment:
If System.Web.Http Context.Current .Session IsNot Nothing Then
If
System.Web.Http Context.Current .Session(SESSIO N_OBJECT_GUID) Is Nothing Then
System.Web.Http Context.Current .Session(SESSIO N_OBJECT_GUID)
= New UserInfo
End If
Return
TryCast(System. Web.HttpContext .Current.Sessio n(SESSION_OBJEC T_GUID),
UserInfo)
Else
Return Nothing 'Throw exception?
End If
End If
End Function
Apr 16 '07 #4

create two different holder classes, an
IObjectHolder interface, and an ObjectHolderFac tory 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 WinformsUserInf o : 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_I P_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.Http Context.Current Then ' Add a reference to
System.Web.dll
'Non Web Environment
return new WinformsUserInf o
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.Http Context.Current Then ' Add a reference to
System.Web.dll
return "IPAddress not available in winforms"

Else 'Web Environment
Return Server(REMOTE_I P_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***@communit y.nospamwrote in message
news:Oh******** ******@TK2MSFTN GP06.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 ObjectHolderFac tory 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 singletonInstan ce 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 singletonInstan ce Is Nothing Then
If System.Web.Http Context.Current Is Nothing Then 'windows
forms
environment:
singletonInstan ce = New UserInfo
Else 'web environment:
If System.Web.Http Context.Current .Session IsNot Nothing
Then
If
System.Web.Http Context.Current .Session(SESSIO N_OBJECT_GUID) IsNot Nothing
Then
singletonInstan ce =
TryCast(System. Web.HttpContext .Current.Sessio n(SESSION_OBJEC T_GUID),
UserInfo)
Else
singletonInstan ce = New UserInfo
System.Web.Http Context.Current .Session(SESSIO N_OBJECT_GUID)
= singletonInstan ce
End If
End If
End If
End If
Return singletonInstan ce
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

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_I P_ADDRESS)
end get
end property

end class
public class WinformsUserInf o : 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.ne twrote in message
news:%2******** ********@TK2MSF TNGP02.phx.gbl. ..
>
create two different holder classes, an
IObjectHolder interface, and an ObjectHolderFac tory 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 WinformsUserInf o : 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_I P_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.Http Context.Current Then ' Add a reference
to
System.Web.dll
'Non Web Environment
return new WinformsUserInf o
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.Http Context.Current Then ' Add a reference
to
System.Web.dll
return "IPAddress not available in winforms"

Else 'Web Environment
Return Server(REMOTE_I P_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***@communit y.nospamwrote in message
news:Oh******** ******@TK2MSFTN GP06.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 ObjectHolderFac tory 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 singletonInstan ce 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 singletonInstan ce Is Nothing Then
If System.Web.Http Context.Current Is Nothing Then 'windows
forms
environment:
singletonInstan ce = New UserInfo
Else 'web environment:
If System.Web.Http Context.Current .Session IsNot Nothing
Then
If
System.Web.Http Context.Current .Session(SESSIO N_OBJECT_GUID) IsNot
Nothing
Then
singletonInstan ce =
TryCast(System. Web.HttpContext .Current.Sessio n(SESSION_OBJEC T_GUID),
UserInfo)
Else
singletonInstan ce = New UserInfo
System.Web.Http Context.Current .Session(SESSIO N_OBJECT_GUID)
= singletonInstan ce
End If
End If
End If
End If
Return singletonInstan ce
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
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~ WebSessionObjec tHolder
and InMemoryObjectH older 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.Http Context.Current Then
return "IPAddress not available in winforms"
Else 'Web Environment
Return Server(REMOTE_I P_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
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.Cu rrent == 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

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 GetUserInfoBase dOnEnvironment 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 EmployeeControl ler

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 .GetUserInfoBas edOnEnvironment ()
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
GetUserInfoBase dOnEnvironment

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.Ge tObjectHolder() '' 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.Ge tObjectHolder() .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 "currentses sion 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***@communit y.nospamwrote in message
news:ua******** ********@TK2MSF TNGP04.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~
WebSessionObjec tHolder
and InMemoryObjectH older 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.Http Context.Current Then
return "IPAddress not available in winforms"
Else 'Web Environment
Return Server(REMOTE_I P_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
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 .GetUserInfoBas edOnEnvironment ()
dim dataLayerObject as EmployeeData
dataLayerObject = new EmployeeData
dataLayerObject .Save (e.SSN, e. LastName, e.FirstName, _
u.UserID)
But with the creation method ("GetInstanc e") 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.GetIns tance.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

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

25
5630
by: David Noble | last post by:
We've been developing a web site using 3-tier architecture for 18 months now. There is a common layer that defines the classes - using XML schemas. The data layer acts as a wrapper to 3 databases - SQL Server, Oracle and AS400. The business layer exposes web services which communicate with the front end, ASP.Net. All 3 tiers are on different boxes. This works well. Now I am leading a team to build a winforms app. I need some advice as
3
1296
by: Johnny Meredith | last post by:
Hi, I'm relaively new to programming languages in general, and brand new to VB.NET. I use/used VBA in MS Access previously to do what I needed. I want to learn VB.NET to stretch my boundaries a bit. Anyway, I'm developing an application to track the progress of tax audits. Originally, I thought I would write objects something like this:
2
1779
by: hans | last post by:
Hi! I am new to .NET (coming from Java). We have to implement a desktop application which extracts data from a database, does some analysis, filtering etc. and displays the results. I have noticed that in .NET applications Windows widgets like the DataGrid are often directly bound to a DataSet Object. For me this means essentially a 2 tier architecture instead of a 3 tier architecture. I am used to seperating the application into 3 tiers:...
0
1105
by: Ed | last post by:
Greetings: Anyone out there aware of any work being done to allow a Microsoft.Net application to make use of the Adobe XML architecture especially in regards to Forms or workflow. It seems that Adobe is persuing a J2EE environment, but I was wondering if anyone has done work to bridge microsoft.net to Adboe XML forms. I am particulary interested in "Open Source" work, but would be curious to know about commercial products also. --
7
1519
by: Dan Walls | last post by:
Hi, I just had a question regarding forms authentication using a SQL database backend. If my (planned)architecture is: Internet -> firewall -> DMZ (IIS - access to User Interface) -> Firewall -> SQL User Database, Application Server, SQL application database. then what technology would I typically use to communicate between the IIS machine in my DMZ and the SQL user database?
3
1103
by: DwC | last post by:
Hey All, I am fairly new to ASP and web apps and am having trouble working out the architecture for the app we are currently working on. It allows a user to log in and have access to pages that wouldn't be available publicly. We also need to check the user id each time data is accessed from the db as users will only have access to their own records. We are from a background of windows forms applications where the standard architecture...
0
1251
by: CodeMonkey | last post by:
Hi, I was wondering if anybody could give me some advice on how to structure an application that I am about to start work on. The vague requirements will be: 1) Always-On monitoring of data (e.g. through serial port and other sources) 2) Local machine user interface 3) Remote machine user interface (networked)
1
2066
by: Lomax | last post by:
Hi ! I have to develop an accounting soft solution. For many reasons we decided to use a three tier architecture. The logical tier is composed of logical components and a web service facade that delegate to the logical components. The presentation will be composed of both a widows forms application and a web forms application. Both applications will access the web service facade either through Internet or an intarnet. Of course, an...
1
1197
by: Craig Buchanan | last post by:
I am building an application to help researcher record the outcomes of their studies. These outcomes are document across a number of paper forms. The information documented on these forms varies widely. My current approach is to use a Document class with a collection of Question classes. I create an instance of the Document, add a number of questions to it, serialize the Document object to XML, then treat this XML file as a...
0
948
by: Craig Buchanan | last post by:
I am building an application to help researcher record the outcomes of their studies. These outcomes are document across a number of paper forms. The information documented on these forms varies widely. My current approach is to use a Document class with a collection of Question classes. I create an instance of the Document, add a number of questions to it, serialize the Document object to XML, then treat this XML file as a...
0
9598
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10623
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10373
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10111
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9192
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6877
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5546
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5683
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3852
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.