I understand the basic differences between structs and class types. But, in an ASP.NET WebForms application...what is the ideal container type to hold a relatively large data structure in Session in an ASP.NET WebForms application? Should it be a struct or class? For example...
Public Structure SessionData
Public ShipVias As List(Of XXXXX999.sycdefil_sql_VW)
Public ShipTos As List(Of XXXXX999.ABC_Web_ShipTo_VW)
Public Dests As List(Of XXXXX999.ABC_Web_CofA_VW)
Public Owners As List(Of XXXXX999.ABC_Web_CofA_VW)
Public Carts As List(Of XXXXX999.ABC_Web_Cart_VW)
Public Carriers As List(Of XXXXX999.ABC_Carrier_Accounts_VW)
Public Countries As List(Of XXXXX999.usp_get_CountryListResult)
Public States As List(Of XXXXX999.usp_get_StatesListResult)
Public POItems As List(Of XXXXX999.usp_get_cart_infoResult)
Public SearchResults As List(Of SearchResult)
Public Addresses As List(Of AddressResult)
Public CartItems As List(Of itemsdetail)
Public POs As List(Of POResult)
Public SomeCollection As Collection
Public CmpCode As String
Public CmpStatus As String
Public CmpSIPCust As String
Public CurrentSession As String
Public AllowAccess As Boolean
Public QuickAddItems As List(Of QuickAddItem)
End Structure
As you can probably tell, XXXXX999 contains a LINQTOSQL DataContext dbml containing sprocs, functions, views and tables.
Edit point: I just realized I can make a struct(C#) to be nullable...In vb.net Nullable(Of SessionData)...also question mark does the trick like so...
Dim sd As SessionData?
Should I keep this as a Structure or convert it to a Class?
Convert it to a class. Based on this MSDN link a struct should only be used if:
Consider defining a structure instead of a class if instances of the
type are small and commonly short-lived or are commonly embedded in
other objects.
Do not define a structure unless the type has all of the following characteristics:
It logically represents a single value, similar to primitive types (integer, double, and so on).
It has an instance size smaller than 16 bytes.
It is immutable.
It will not have to be boxed frequently.
if you are dealing with distinct values I would use a dictionary that hold dictionaries for every type of list
Related
I have a WEB Method in my ASPX page that retrieves a List from SQL DB using Entity Framework.
Using rep As New RBZPOSEntities
q = rep.getSalesByLocation(fDate, tDate).ToList
End Using
Thereafter i use javascriptserializer to convert this list into a JSON string
Dim jss As JavaScriptSerializer = New JavaScriptSerializer()
Dim json As String = jss.Serialize(q)
So the above works great and i can use AJAX on the client side to display the results successfully.
The problem i am having now is converting a Flat List into a Nested JSON string.
So consider a list like:
locationName as string
MonthName as string
totalAmount as string
Which needs to be converted into a JSON like this:
[{locationName:'Tokyo',totalAmount:[100,200,300,400]},
{locationName:'New York',totalAmount:[500,600,700,800]}]
So the totalAmount values in the above case correspond to totalAmounts for a Location for a specific month. E.g. Tokyo total amount in January is 100, in February is 200 and etc.
What i can do:
I can create a nested list and populate it with results from EF and then serialize to JSON.
What i am asking:
Is there any other cleaner way to do it.
Thank you
As Todd has already said you need to convert your flat list into a list of another intermediate type. Let's call your existing Type the "InputType" and the Type you want the "OutputType"
Public Class InputClass
Public locationName as String
Public MonthName as String
Public totalAmount as String
End Class
Public Class OutputClass
Public LocationName As String
Public TotalAmount As List(Of String)
Public Sub New(groupedInputClass As IGrouping(Of String, InputClass))
LocationName = groupedInputClass.Key
TotalAmount = groupedInputClass.Select(Function(x) x.totalAmount).ToList()
End Sub
End Class
Then all you need to do is transform a List of InputType into a List of OutputType which is really easy with LINQ.
Public Class MappingHelper
Public Function Map (inputList as List(Of InputClass)) As List(Of OutputClass)
Dim groupedByLocation = inputList.GroupBy(Function(k) k.LocationName)
Dim nestedLocations = groupedByLocation.Select(Function(x) new OutputClass(x)).ToList()
Return nestedLocations
End Function
End Class
If you use an intermediate type, it may be helpful. Something like:
class RbzposInfo {
public string Location {get;set;}
public List<MonthlyRevenue> Monthlies {get;set;}
}
class MonthlyRevenue {
public string Month {get;set;}
public int Revenue {get;set;}
}
var result = new List<RbzposInfo>();
foreach (var r in q) { // q from your code
var info = new RbzposInfo();
// TODO: put r values into info.
result.Add(info);
}
Dim json As String = jss.Serialize(result);
(PS, sorry I mixed .NET languages on you. My code is C#.)
The following class is used in an ASP.NET application to read currencies from a database result set and add them up (e.g. show totals in US Dollars plus show totals in GB Pounds). It works in the following manner:
Read currency ID value
If currency ID exists already, increase the total for that currency
If currency ID does not exist, add it to the list with its value
Next
It works well using the CurrencyID property as the differentiator between each unique currency. However, it has now become apparent that IsoCurrencySymbol is also unique for each currency by default, and so CurrencyID is not actually needed.
So... I was wondering if it would be possible to inherit from this class and remove any reference to CurrencyID, therefore making the CompareTo method use IsoCurrencySymbol instead.
The trick is to leave the existing class as it is used extensively, but introduce a modified version without CurrencyID being needed. Is this possible to do please?
<Serializable()> _
Public Class CurrencyCounter
<Serializable()> _
Private Class CurrencyType
Implements IComparable
Public IsoCurrencySymbol As String
Public CurrencySymbol As String
Public CurrencyID As Int16
Public Amount As Decimal
Public Function CompareTo(obj As Object) As Integer Implements System.IComparable.CompareTo
If Not TypeOf (obj) Is CurrencyType Then
Throw New ArgumentException("Object is not a currency type")
Else
Dim c2 As CurrencyType = CType(obj, CurrencyType)
Return Me.CurrencyID.CompareTo(c2.CurrencyID)
End If
End Function
End Class
Private _Currencies As List(Of CurrencyType)
Public Sub New()
_Currencies = New List(Of CurrencyType)
End Sub
Private Sub AddStructToList(CurrencyID As Integer, IsoCurrencySymbol As String, CurrencySymbol As String, Amount As Decimal)
If IsoCurrencySymbol <> String.Empty AndAlso Amount > 0 Then
Dim s As New CurrencyType
s.CurrencyID = CurrencyID
s.IsoCurrencySymbol = IsoCurrencySymbol
s.CurrencySymbol = CurrencySymbol
s.Amount = Amount
_Currencies.Add(s)
End If
End Sub
Public Sub Add(CurrencyID As Integer, IsoCurrencySymbol As String, CurrencySymbol As String, Amount As Decimal)
Dim ct As CurrencyType = _Currencies.Find(Function(obj) obj.CurrencyID = CurrencyID)
If ct IsNot Nothing Then
ct.Amount += Amount
Else
AddStructToList(CurrencyID, IsoCurrencySymbol, CurrencySymbol, Amount)
End If
End Sub
Public Sub Clear()
_Currencies.Clear()
End Sub
Public Function Count() As Integer
Return _Currencies.Count
End Function
Public Function RenderTotals() As String
' ...
End Function
End Class
No, you cannot do that. The whole point of inheritance it to ensure that all derived classes, if nothing else, at least share the same public interface as their base class. If you are removing a property, then it doesn't share the same interface and is therefore incompatible and not a candidate for inheritance.
If you can't say that the derived class is a type of the base class, then you can't use inheritance. For instance, I can say that an automobile is a type of vehicle, therefore, if I had an automobile class, I could have it inherit from a vehicle class. I can't however say that an insect is a type of vehicle. Therefore, even if they share most things in common, I can't have an insect class inherit from a vehicle class.
The reason for this limitation is because inheritance allows you to treat an object as if it were the base type (via type casting). For instance:
Public Sub AddPassengerToVehicle(v As Vehicle)
v.Passengers.Add(New Passenger())
End Sub
' ...
Dim auto As New Automobile()
Dim bug As New Insect()
AddPassengerToVehicle(auto) ' Works because an automobile is a type vehicle (inherits from vehicle)
AddPassengerToVehicle(bug) ' Can't possibly work (nor should it)
So, if you are in a situation where you need to have a derived class that removes/hides one of the members of its base class, you are headed in the wrong direction. In a case like that, you would need to create a whole new class which just happens to have a very similar interface, but has no direct relationship with the first class, for instance:
Public Class Vehicle
Public Property Passengers As List(Of Passenger)
Public Property MaxSpeed As Integer
Public Function SpeedIsTooFast(speed) As Boolean
Return (speed > MaxSpeed)
End Function
End Class
Public Class Insect
Public Property MaxSpeed As Integer
Public Function SpeedIsTooFast(speed) As Boolean
Return (speed > MaxSpeed)
End Function
End Class
If you want to share functionality, such as the logic in the SpeedIsTooFast method in the above example, then there are a couple different ways to do that. This first would be to make wrapper methods which simply make calls to the other class, for instance:
Public Class Insect
Private _vehicle As New Vehicle()
Public Property MaxSpeed() As Integer
Get
Return _vehicle.MaxSpeed
End Get
Set(value As Integer)
_vehicle.MaxSpeed = value
End Set
End Property
Public Function SpeedIsTooFast(speed) As Boolean
Return _vehicle.SpeedIsTooFast(speed)
End Function
End Class
If you do it this way, it would be best to have both classes implement the same common interface so that you can use them interchangeably when necessary, for instance:
Public Interface ISelfPoweredMovingThing
Property MaxSpeed As Integer
Function SpeedIsTooFast(speed As Integer) As Boolean
End Interface
Another option would be to break out the common functionality into a third class and then use that class as the base for the other two, for instance:
Public Class SelfPoweredMovingThing
Public Property MaxSpeed As Integer
Public Function SpeedIsTooFast(speed) As Boolean
Return (speed > MaxSpeed)
End Function
End Class
Public Class Vehicle
Inherits SelfPoweredMovingThing
Public Property Passengers As List(Of Passenger)
End Class
Public Class Insect
Inherits SelfPoweredMovingThing
' Anything else specific only to insects...
End Class
In my ASP.NET Web Service I've included a module in which their are Public declared variables. Will they be thread-safe? Will they get mixed up upon simultaneous calls?
Those variables are mostly DatsSet, DataTable and SQLDataAdapter..
Partial code of the module:
Imports System.Data.OleDb
Imports System.Diagnostics
Module modCommon
Public bDoLog As Boolean
Public sCurrentODBC As String
Public cn As SqlConnection
Public Query1ds As DataSet
Public Query1 As DataTable
Public Query1adapter As SqlDataAdapter
#scripni
Thanks, as I'm not familiary with your suggestions, I will move everything locally.
Additionally, will the following variables be thread-safe?:
[ToolboxItem(False)]_
Public Class Service1
Inherits System.Web.Services.WebService
Dim sName As String
Dim sCurrentPath As String
[WebMethod()]_
Public Function Capture(ByVal sPath As String) As String
sName = "Joe"
End Function
End Class
If you're using web services than yes, you will have concurency problems when multiple services will try to access the same resource, and SqlConnection is definetly a resource you don't want shared.
You should make sure that you don't have simultaneous calls to the properties (for ex. by wrapping the fields with getters / setters and implementing locks in those methods) or by moving the code to a class and instantiating that class whenever you need it.
I grabbed an example off of this SO question, and built my own custom Google Maps object used for deserializing the json object.
Now the code works like a champ, but I just need an explanation on why/how it works. Does the serializer "try" to match up names, or is something else going on.
What exactly is this doing?
Here's the working code.
Imports System.Net
Imports System.Web
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Json
Imports System.Web.Script.Serialization
Namespace Utilities.Apis
Public NotInheritable Class GoogleGeolocate
Private Const googleUrl As String = "http://maps.googleapis.com/maps/api/geocode/json?address={0}&sensor=false"
Private Sub New()
End Sub
Public Shared Function GetLatLon(ByVal address As String) As String
''# This is just here to prevent "placeholder" data from being submitted.
If address = "6789 university drive" Then
Return Nothing
End If
address = HttpUtility.UrlEncode(address)
Dim url = String.Format(googleUrl, address)
Dim request = DirectCast(HttpWebRequest.Create(url), HttpWebRequest)
request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate")
request.AutomaticDecompression = DecompressionMethods.GZip Or DecompressionMethods.Deflate
Dim serializer As New DataContractJsonSerializer(GetType(GoogleResponse))
Dim res = DirectCast(serializer.ReadObject(request.GetResponse().GetResponseStream()), GoogleResponse)
Dim resources As GoogleResponse.Result = res.results(0)
Dim point = resources.geometry.location.lat
Dim latlon As New GeolocationLatLon
With latlon
.latitude = resources.geometry.location.lat
.longitude = resources.geometry.location.lng
End With
Dim jsonSerializer = New JavaScriptSerializer
Return jsonSerializer.Serialize(latlon)
End Function
End Class
<DataContract()>
Public Class GoogleResponse
<DataMember()>
Public Property results() As Result()
<DataContract()>
Public Class Result
<DataMember()>
Public Property geometry As m_Geometry
<DataContract()>
Public Class m_Geometry
<DataMember()>
Public Property location As m_location
<DataContract()>
Public Class m_location
<DataMember()>
Public Property lat As String
<DataMember()>
Public Property lng As String
End Class
End Class
End Class
End Class
End Namespace
And here's the GeolocationLatLon Poco
Public Class GeolocationLatLon
Public latitude As String
Public longitude As String
End Class
When I call the code, it's really quite simple.
note, this is an MVC controller, that has nothing to do "really" with the question other than to show what I'm doing
Function GeoLocation(ByVal address As String) As ContentResult
Return New ContentResult With {.Content = GoogleGeolocate.GetLatLon(address),
.ContentType = "application/json"}
End Function
And the final result is
{"latitude":"50.124300","longitude":"-114.4979990"}
Internally, DataContractJsonSerializer maps JSON name/value pairs to an XML infoset. In fact, DataContractJsonSerializer is built on top of the XML-based DataContractSerializer and processes every JSON input and JSON output as if it were dealing with XML. There is a higher-level abstraction layer (a JSON writer and a JSON reader, as exposed via JsonReaderWriterFactory) that actually translates this XML to JSON and JSON back to internal XML.
See this excellent overview (Mapping Between JSON and XML) to see what happens to DataContractJsonSerializer internally and how it pulls all this off.
I'm building a decent sized application in ASP.NET/VB.NET with various objects... I've never used interfaces before, and a fellow programmer balked when I mentioned this to him. Can anyone give me a quick overview on how they're used, what they're used for, and why I would use them? Maybe I don't need to use them for this project, but if they would help, I surely would love to try.
Thanks so much!
Once you "get" interfaces, OOP really falls into place. To put it simply, an interface defines a set of public method signatures, you create a class which implements those methods. This allows you generalize functions for any class which implements a particular interface (i.e. classes which have the same methods), even if those classes don't necessarily descend from one another.
Module Module1
Interface ILifeform
ReadOnly Property Name() As String
Sub Speak()
Sub Eat()
End Interface
Class Dog
Implements ILifeform
Public ReadOnly Property Name() As String Implements ILifeform.Name
Get
Return "Doggy!"
End Get
End Property
Public Sub Speak() Implements ILifeform.Speak
Console.WriteLine("Woof!")
End Sub
Public Sub Eat() Implements ILifeform.Eat
Console.WriteLine("Yum, doggy biscuits!")
End Sub
End Class
Class Ninja
Implements ILifeform
Public ReadOnly Property Name() As String Implements ILifeform.Name
Get
Return "Ninja!!"
End Get
End Property
Public Sub Speak() Implements ILifeform.Speak
Console.WriteLine("Ninjas are silent, deadly killers")
End Sub
Public Sub Eat() Implements ILifeform.Eat
Console.WriteLine("Ninjas don't eat, they wail on guitars and kick ass")
End Sub
End Class
Class Monkey
Implements ILifeform
Public ReadOnly Property Name() As String Implements ILifeform.Name
Get
Return "Monkey!!!"
End Get
End Property
Public Sub Speak() Implements ILifeform.Speak
Console.WriteLine("Ook ook")
End Sub
Public Sub Eat() Implements ILifeform.Eat
Console.WriteLine("Bananas!")
End Sub
End Class
Sub Main()
Dim lifeforms As ILifeform() = New ILifeform() {New Dog(), New Ninja(), New Monkey()}
For Each x As ILifeform In lifeforms
HandleLifeform(x)
Next
Console.ReadKey(True)
End Sub
Sub HandleLifeform(ByVal x As ILifeform)
Console.WriteLine("Handling lifeform '{0}'", x.Name)
x.Speak()
x.Eat()
Console.WriteLine()
End Sub
End Module
None of the classes above descend from one another, but my HandleLifeform method is generalized to operate on all of them -- or really any class which implements the ILifeform interface.
Since the basics have already been covered, lets move on to practical examples.
Say I'm going to have a Dictionary that stores String keys and Person objects and I'm going to pass this dictionary (actually, the reference to it) to some methods I have.
Now, my receiving method would look something like
Imports System.Collections.Generic
Public Sub DoSomething(ByVal myDict As Dictionary(Of String, Person))
' Do something with myDict here
End Sub
right?
But what if someone invents some new high performance dictionary class? I have to turn around and change every reference to Dictionary to FastDictionary!
However, if I had coded to the interface in the first place, I wouldn't have this problem:
Imports System.Collections.Generic
Public Sub DoSomething(ByVal myDict As IDictionary(Of String, Person))
' Do something with myDict here
End Sub
Now it takes any dictionary!
Interfaces basically allow you to define a type's contract without specifying its implementation.
The idea is that if you know that a given type implements a certain interface it is guaranteeing that certain methods and properties are members of that type.
So any type that implements the following interface:
Interface ISpinnable
Sub Spin()
End Interface
Would have to implement the Spin method. But the caller of this type that implements ISpinnable does not care about how it is implemented, it just cares that the method is there. Here is a type that implements ISpinnable:
Class Top Implements ISpinnable
Sub Spin()
' do spinning stuff
End Sub
End Class
The benefit to this is that you can create method arguments of type ISpinner and allow the caller of these methods to pass any type to you as long as it implements the interface. Your method is no longer tightly coupled to the concrete type that the caller is using.
An interface is a contract without an implementation. It allows you to define what a type will look like without indicating what the implementation of that type is.
This allows you to have various implementations of an interface, which would suit your particular needs.
A good example is the IComparer(Of T) interface. You can have one implementation that will compare two items based on which is greater, and then another which will return a value based on which is lesser.
Then, you could pass one or the other to the static Sort method on the Array class to sort your items in ascending, or descending order, respectively.
One of the things interfaces can be useful is browsing through the array of objects of different types but which share the same interface.
Can't say for VB, but in C# you can use the handy "is" operator to determine if object's type implements the given interface and it's safe to access methods of that interface by casting. Sorry for C#, but i'll try to put some comments in =))
//we declare 3 different interfaces each requiring to implement one method
interface IProgrammer
{
void WriteCode();
}
interface ITester
{
void FindBugs();
}
interface IWorker
{
void StartShift();
}
// each programmer will be able to start his shift and write code
class Programmer : IWorker, IProgrammer
{
public void StartShift()
{
// ...
}
public void WriteCode()
{
// ...
}
}
// each tester will be able to start his shift and find bugs
class Tester : IWorker, ITester
{
public void StartShift()
{
// ...
}
public void FindBugs()
{
// ...
}
}
//then in code you can rely on objects implementing the interface to
// be able to do tasks interface requires to do
static void Main()
{
IWorker[] workers = new IWorker[3];
workers[0] = new Programmer();
workers[1] = new Tester();
workers[2] = new Tester();
// now we can browse through array of different workers because they all share
// the IWorker interface
foreach(IWorker worker in workers)
{
// All IWorkers can StartShift so we access its methods without casts
worker.StartShift();
if(worker is IProgrammer)
{
// Since that worker also implements IProgrammer
// we cast worker as IProgrammer and access IProgrammer method(s)
(worker as IProgrammer).WriteCode();
}
if(worker is ITester)
{
// Same,
// we cast worker as ITester and access ITester method(s)
// handy! =)
(worker as ITester).FindBugs();
}
}
A classic example is the Data Layer where you use it to support multiple database format. This was actually very useful before ORMappers came into the picture in mainstream programming.
Your interface just tells what type of method and properties your object has, the object itself then has to implement these methods.
IMyDatabase myDb;
switch case myDbFormat {
case "mysql":
myDb = new MyDbMySql();
break;
case "mssql" :
myDb = new MyDbMsSql();
break;
}
myDb.SaveToDatabase(some data)
Ofcourse the myDb classes have to implement the ImyDatabase Interface. I assume you can see how useful this is :).