Using the same class library in WinForms and WebForms projects

  • Thread starter Thread starter David Jackson
  • Start date Start date
D

David Jackson

Hello,

Following advice from Gregory A. Beamer, I have written a C# class library
which contains several base classes to provide functionality such as
database access, mail, encryption and so on.

This class library is intended to be reused unmodified in all subsequent
WinForms and WebForms development in Visual Studio.NET 2008 / C'#.

For WinForms projects, I want the class library to fetch the database
ConnectionString from the main application's config file. No problem with
that:
connectionString =
System.Configuration.ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString);

But, for WebForms, I want the class library to fetch it from the main web
app's Application cache. We're a small company and have only one database
so, to avoid opening and reading web.config every time we need to access the
database, we fetch the ConnectionString out of web.config in
Application_Start and store it as an Application variable:
protected void Application_Start(Object sender, EventArgs e)
{
Application["SQLConnectionString"] =
System.Configuration.ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString);
}

Then when it's needed again it can be fetched out of Application memory:
connectionString =
System.Web.HttpContext.Current.Application["SQLConnectionString"].ToString();

This now presents me with two problems.

1. I can't seem to find any way for the class library to work out if it's
being used by a WinForms project or a WebForms project. I could include an
extra parameter with all the class library's methods, I suppose, but at that
point I may as well just pass the connection string anyway! Can anyone
please tell me if a class library knows what type of project it is being
referenced in? I have tried to find a way with Reflection but confess that
that is a bit out of my league at the moment.

2. When the class library is being used in a WebForms project it seems to be
able to work with the main web app's Application cache only when running on
my local development machine. When I deploy it to the test webserver it is
unable to find it. Has anyone seen this behaviour before and knows what I've
missed?

Thank you.

DJ
 
Write a simple factory, encapsulate the logic.



public static ISomeObject GetSomeObject( )
{


if ( null == System.Web.HttpContext.Current ) // Add a reference to
System.Web.dll (in the BAL assembly most likely)
{ //Non Web Environment
return new NonWebSomeObjectConcrete();
}
else
{ //Web Environment
return new WebSomeObjectConcrete();
}

}
}


ISomeObject is the interface. Create a concrete one for the web
environment, a different concrete version for the nonweb environment.


You could just return a string I guess instead of ISomeObject.





David Jackson said:
Hello,

Following advice from Gregory A. Beamer, I have written a C# class library
which contains several base classes to provide functionality such as
database access, mail, encryption and so on.

This class library is intended to be reused unmodified in all subsequent
WinForms and WebForms development in Visual Studio.NET 2008 / C'#.

For WinForms projects, I want the class library to fetch the database
ConnectionString from the main application's config file. No problem with
that:
connectionString =
System.Configuration.ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString);

But, for WebForms, I want the class library to fetch it from the main web
app's Application cache. We're a small company and have only one database
so, to avoid opening and reading web.config every time we need to access
the database, we fetch the ConnectionString out of web.config in
Application_Start and store it as an Application variable:
protected void Application_Start(Object sender, EventArgs e)
{
Application["SQLConnectionString"] =
System.Configuration.ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString);
}

Then when it's needed again it can be fetched out of Application memory:
connectionString =
System.Web.HttpContext.Current.Application["SQLConnectionString"].ToString();

This now presents me with two problems.

1. I can't seem to find any way for the class library to work out if it's
being used by a WinForms project or a WebForms project. I could include an
extra parameter with all the class library's methods, I suppose, but at
that point I may as well just pass the connection string anyway! Can
anyone please tell me if a class library knows what type of project it is
being referenced in? I have tried to find a way with Reflection but
confess that that is a bit out of my league at the moment.

2. When the class library is being used in a WebForms project it seems to
be able to work with the main web app's Application cache only when
running on my local development machine. When I deploy it to the test
webserver it is unable to find it. Has anyone seen this behaviour before
and knows what I've missed?

Thank you.

DJ
 
Hi Sloan,

Thank you for replying.
Write a simple factory, encapsulate the logic.

if ( null == System.Web.HttpContext.Current )

I am essentially doing exactly that. The problem is that it seems to work
only when running in Visual Studio 2008 on my development machine but when I
deploy it to the test server it doesn't. By that I mean that on the test
server it ALWAYS thinks it's running in a WinForms project even when it's
running in a WebForms project.

Any ideas why this might be?

DJ
 
is there some reason why you are afraid to read from the web.config?
If you're worried about it being a performance issue you're probably
way off base.
 
Is there some reason why you are afraid to read from the web.config?

I'm not afraid of anything - what a strange question!
If you're worried about it being a performance issue you're probably
way off base.

That's possible. Can you please expand on this, specifically about how
reading a value out of web.config once and then caching it in Application
memory is not more efficient than reading it out of web.config thousands and
thousands of times?
 
I'm not afraid of anything - what a strange question!


That's possible. Can you please expand on this, specifically about how
reading a value out of web.config once and then caching it in Application
memory is not more efficient than reading it out of web.config thousands and
thousands of times?

Test it empirically:
DEFAULT.ASPX
<%@ Page Language="VB" AutoEventWireup="false"
CodeFile="Default.aspx.vb" Inherits="_Default" Trace="true" %>

DEFAULT.ASPX.VB
Partial Class _Default
Inherits System.Web.UI.Page

Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.PreRender

Application("test") =
Web.Configuration.WebConfigurationManager.ConnectionStrings
("test").ConnectionString
Dim Iterations As Integer = 99999
Dim ApplicationTestArr(Iterations) As String
Dim WebConfigTestArr(Iterations) As String

Trace.Write("Application Test Start")
For i As Integer = 0 To Iterations
ApplicationTestArr(i) = Application("test")
Next
Trace.Write("Application Test End")

Trace.Write("Web.config Test Start")
For i As Integer = 0 To Iterations
WebConfigTestArr(i) =
Web.Configuration.WebConfigurationManager.ConnectionStrings
("test").ConnectionString
Next
Trace.Write("Web.config Test End")

End Sub
End Class

WEB.CONFIG
....
<connectionStrings>
<add name="test"
connectionString="datasource=test1;database=test2;integrated
security=true;"/>
</connectionStrings>
....

In the trace you will see something like this:

Message From First(s) From Last(s)
....
Application Test Start 0.00154236 0.001313
Application Test End 0.13982672 0.138284
Web.config Test Start 0.1399284 0.000102
Web.config Test End 0.40322772 0.263299
....

The difference is about 13 tenths of a second over a hundred thousand
iterations!
AKA it takes approx. 1 thousandth of a thousandth of a second longer
to read it from the web.config (.000001 seconds)

I realize that this test may be somewhat simplistic, but its a start.

- Norm

Note: There is one advantage (that I can think of) to putting it in
memory: You can change it without restarting the application. (Editing
the web.config forces restart)
 
Back
Top