In my asp.net web app. I have three classes (inside app_code folder) under namespace WPP which are as follows:
1. wpp_Common
2. wpp_SQL
3. wpp_Admin
All these classes contains different functions which I am using in my application to accomplish different tasks. Such as, wpp_common contains a function which make my URL's SEO'd, and wpp_SQL have some functions which I am using to get details from database.
Now, I am using these classes on different web pages web pages and in web controls. To use these classes I am creating instances of all three classes on the page where I am using them.
protected WPP.wpp_Common ObjCommon = new WPP.wpp_Common();
protected WPP.wpp_SQL ObjSQL = new WPP.wpp_SQL();
protected WPP.wpp_Admin ObjAdmin = new WPP.wpp_Admin();
So, I want to know, is this a better and only way to access my classes by making seprate instances at every page, is this method have any performance constraints.
Or is there a better and logical way to access my classes from ASP.net web pages and web controls.
Thanks.
If these classes don't encapsulate anything mutable, it may be worth making the key methods utilized static. Then, you don't even need an instance of the class. This seems to make sense for your SEO class. The SQL class you may want a shared instance as it may contain a reference to some SQL connection/class, but this could also be a parameter in a static method.
What you're doing seems okay to me, though.
Really the answer boils down to the complexity of the class. If your classes are lightweight and have low initialization overhead, then you are probably OK with instatiating objects every time. (Heck, even the ASP.NET runtime creates a new instance of your page object every time in classic ASP.NET - not sure about MVC).
But if your object has non-trivial initialization time (intensive processing in constructor or upon first method call), then you'll probably want to look at two options:
One) Storing the object in the session - be careful here as your object may behave differently depending on the backend session store (memory, sql, etc).
MyHeavyObj obj = (MyHeaveyObj) Session["cachedObj"];
if (obj == null)
{
obj = new MyHeavyObj();
obj.Init();
Session["cachedObj"] = obj;
}
obj.DoSomething();
Two) Writing your own Windows Service that serves up your objects via remoting and takes care of initiatlization internally. The drawback here is you need to make sure your service scales as your traffic grows.
MyHeavyObj obj = GetHeavyObjViaRemoting();
obj.DoSomething();
Related
I am working with an app that handles appointment scheduling.
Right now what I am doing is generating a list of people to call for confirmations in a confirmations section and a list of people to call for rescheduling in a rescheduling section.
I have two separate, but very similar (nearly identical) domain classes for the confirmation items and the rescheduling items.
I have two nearly identical methods in my scheduling service that handle list generation.
I would like to only use one method in the service that would handle the list generation for both of these. The only real difference between the two service methods is which table is being referenced.
My problem is that I can't dynamically change which domain class I am using based on what mode the user is interacting with (confirmations/rescheduling). I get a cannot implicitly convert type error.
I thought a solution would be to create a parent domain class "scheduling item" and have the confirmation item and scheduling item be children of that. However, I still can't figure out how to reference them in the service method.
I thought I could declare a var and then assign it to whichever domain I wanted based on the mode the user is in. That also gets an error because it wants the var's type to be declared in advance.
I am relatively new to C# and I could really use some advice on the best way to simplify this and not have two nearly identical sets of code.
I realize I could just use one class for both, but that would not be ideal, because I would like to keep the data separate for the two domains.
I cannot share the actual code. I figure with the information I have given though, someone might be able to tell me how to handle one service method for two related domain classes.
Thanks in advance for any help you can offer.
To clarify, our set up is like this:
There is a class ConfirmationItem and a class ReschedulingItem that are models for the Mongo database tables.
The Scheduling Service has two methods currently that are "GenerateConfirmationItemList"/"GenerateReschedulingItemList".
The way these methods access the data is like this:
var confirmationItems = GenericRepository.Table<ConfirmationItem>().Where(...).ToList();
var reschedulingItems = GenericRepository.Table<ReschedulingItem>().Where(...).ToList();
Other than these initial table references, the logic is identical.
What would be really helpful is if I could have the method choose which table to use based on what mode we are in (Confirmation or Rescheduling).
However, if I try something like:
var scheduling items;
switch(mode)
case "confirmation":
{
schedulingItems = GenericRepository.Table<ConfirmationItem>().Where(...).ToList();
}
This gets an error because implicitly typed vars have to be assigned.
I am currently using EF 6 to do the following. Execute a stored procedure, then bring in the data I need to use. The data is usually 30-40 rows per application run.
I then iterate over the var, object, table (whatever you would like to call it), performing similar (sometimes different) tasks on each row. It works great. I am able to create an Entity object, expose the different complex functions of it, and then create a var to iterate over.
Like:
foreach (var result in StoredProcedureResult)
{
string strFirstname = result.FirstName
string strLastName = result.LastName
//more logic goes here using those variables and interacting with another app
}
I recently thought it would be cool if I had a class solely for accessing the data. In this way, I could just reference that class, toss the corresponding connection string into my app.config, and then I can keep the two sets of logic separate. So when attempting to do the above in that structure, I get to the point at which, you can't return a var, or when I attempt to match object return type. The return type of the execution of a stored procedure is object (which I can't iterate on).
So my question is, how does one get to the above example, except, the var result, get returned from this data access class?
If I am missing something, or its not possible because I am doing this incorrectly, do let me know. It appeared right in my head.
I'm not going to describe the architecture in full. But based on your comments you can do the following (this is not the definitive nor the only way how to do it):
in your data access project you keep the DBContext class, all the code for the stored procedure call and also the class that defines the result of the SP call, let's call it class A;
in your shared layer project - I would suggest calling it Service layer - you can create a XYService class, that has a method e.g. GetListOfX that connects to the DB and calls the procedure, if needed this method can also perform some logic, but more importantly: it doesn't return class A, but returns a new class B (this one is defined in the service layer, or can be defined in yet another project - that might be the true shared/common project; as it would be just a definition of common structures it isn't really a layer);
in your application layer you work only with the method GetListOfX of the XYService and the class B, that way you don't need a reference to the data access project
In a trivial case the class B has the same properties as the class A. But depending on your needs the class B can have additional properties/functionality it can also ignore some properties of A or even combine multiple properties into one: e.g. combining the FirstName and LastName as one property called simply Name.
Basically what you are looking for is the multi-tier application architecture (usually 3-4 tier). The full extent of such approach (which includes heavy usage of concepts like interfaces and dependency injection) might not be suitable or needed based on your goals, e.g. if you are building just a small application for yourself with a couple of functions or you know there won't be any reuse of the components of the final solution, then this approach is too wasteful and you can work faster with everything in one project - you should still apply principles like SOLID, DRY and Separation of concerns.
Question:
Normally, one accesses the session object like this:
Session["foo"] = "bar";
I have written a wrapper over it, which is generic, and which checks whether a session has expired or not, and throws a SessionExpiredException if that is so.
In order to use my session access, I have to access sessions over my class like this
WebApplications.SessionAccess.Set<string>("foo", "bar");
Now, obviously, despite the presence of the class SessionAccess, one could still access the session via the normal session object. This is not desirable, and additonally, I want to later include it in a larger old project which has been written using the normal Session, which would mean I would have to replace all calls to session (a number in the low thousands) with my wrapper.
Is there a way I can overwrite the System.Web.HttpSessionStateBase.Controller.Session - Property with my own ?
The thing is, without a custom session handler defined in web.config, because there sometimes already is one for using the database for sessions (one could still initialize a module in Global.asax).
Those NULL-Reference exception YSODs on SessionTimeout are hyper-disturbing.
If possible, a solution that works on classical ASP.NET web-forms as well as on MVC.
I don't think that there will be any full-proof solution as you wants it but few tricks can make your life easier.
Create yet another wrapper that provides indexer property so that you can easily substitute calls such as Session["key"] = "name" to your wrapper property;
You need to inherit all your pages (i.e. code-behind classes) from a common base page class (that itself has inherited indirectly from System.Web.UI.Page). If you already have such base page then you are really in good situation. Inherit your common page base class from an internal base class that itself inherited from System.Web.UI.Page.
In the common page base, add a new Session property that would return your wrapper object created in #1. Similar trick has to be done for UserControl (and custom control) if you have many of them. This will save you from replacing the most of Session["key"] = "name" kind of calls.
Finally, override Session property in the internal base page class to add a debug assertion. You may choose to return null but that would break production usage. Debug assertion is a lot better to find session usage that will be escaped from #3.
As said, this is not a full-proof solution as one can still access the session state via HttpContext. But it should make the migration of legacy code to your session accessor object easier.
I'm fairly new to .Net... I have several queries which will execute when the application loads. I want these queries to store the data in an object (a dataset?) which is accessible throughout the application. Should I be using a singleton class? How can a User Control within my application reference public variables in the main application code?
I guess I haven't found a good resource on how / where to store application variables and how to reference them when I need to populate a ListBox, DataGridView, etc.
As a background I'm most familiar with developing using Flex Builder 3, sorry for the vague question... I'm having a problem locating a good reference on the topic (not just populating a Control, but storing the data at an application level and referencing it from anywhere within the app).
Edit: This is for programming a windows forms application using C#
Sounds like you're using ASP.NET, in which case Application State (MSDN) will allow you to store and retrieve application-wide data that can be accessed from anywhere in the application.
More here:
How to: Save Values in Application State
How to: Read Values from Application State
If you're writing a desktop app, you should create a static class that contains your application wide data, e.g:
public static class ApplicationSettings
{
public static string InstallDirectory { get { ... } set { ... } };
public static DataSet SomeDataSet { get { ... } set { ... } };
static ApplicationSettings()
{
// ... initialize or load settings here
}
}
A singleton isn't necessary here, but if you do require lazy initialization and thread satefy you might want to take that route.
You could store the information in a App.config file and use the AppSettingsReader class to access the data.
EDIT: Seeing that you don't want to query the information multiple times, you could use a Singleton to access and cache the data.
Presumably your objects will be required as long as the application's main form is open. If so, simply store them as properties of the form.
Singletons are bad, m'kay? ;)
Or, more to the point, global data (especially mutable global data) is generally not a good thing. It makes classes difficult to test and debug. Small scope is good scope.
One option is to look at an IoC Container library (aka a DI framework).
IoC = Inversion of Control
DI = Dependency Injection (or Inversion)
Basically you can set up constructors on your classes that need access to the global data and add a parameter of your "singleton" type - except it's not a singleton, just a Plain Old Object (or interface). Then you tell the Container that your "global data" class has a long lifespan, and use the Container to create your other objects. You won't use the "new" keyword much anymore. The benefit is that the Container will automagically wire everything up for you, creating one and only one instance of the global class and injecting it in to all of the other constructed objects.
Here's an (incomplete) list of the libraries/frameworks for .NET:
IoC Container Benchmark
Ninject's another one. I use Unity, but that doesn't mean it's the best for you.
Here's another list:
http://elegantcode.com/2009/01/07/ioc-libraries-compared/
I am using jQuery to retrieve a JSON object from a page method. I have a DAL which uses SubSonic and if I return objects created from SubSonic-generated classes I will clog up the pipes. :) You know, all public properties get serialized. I don't want a separate business layer for this application, because it's small and focused on read operations and yet another layer seems like an overkill. To avoid downloading some SubSonic bloated objects (possibly with sensitive information as well) and avoid building a separate layer I tried returning a list of objects, like this:
[WebMethod]
public static List<object> GetFiles()
{
FileCollection collection = DB
.Select()
.From(DataAccess.File.Schema)
.ExecuteAsCollection<FileCollection>();
List<object> files = new List<object>(collection.Count);
foreach (DataAccess.File file in collection)
{
files.Add(new {
file.FileId,
file.ApplicantFirstName,
file.ApplicantLastName,
file.UploadDate
}
);
}
return files;
}
It works and I get a nice JSON object in return (disregard the DateTime value):
[{"FileId":1,"ApplicantFirstName":"Paweł","ApplicantLastName":"Krakowiak","UploadDate":"\/Date(1235656448387
)\/"}]
Is this a good approach? I am concerned about List<object> - is it worse than returning say a List<SomeDomainObject>? Performance? Something else?
This is .NET 2.0, I can't use 3.5 features. At least anonymous types work...
The biggest recommendation might be to make it a "Collection" rather than a List, but with a simple webservice return, it isn't as big of a deal, as that recommendation is most typically in environments where the object still lives in a .NET assembly.
I think it is easy to read as well.
The only downside to using List<object> instead of List<SomeDomainObject> in this scenario would be losing strongly-typed access when calling your GetFiles method directly from .net code.
Looks like there's nothing wrong with my approach. All that I want to do is to return a JSON object to the calling client (browser) to update the UI. This application does 99% read operations, so I am fine with it. I actually started adding a Services and Domain (I keep my business entities here) layers, but I'm going to throw them away. I really try to keep it simple for this application and don't add stuff I don't need.