Tuesday, September 11, 2012

Oledb and sql provider parameter treatment




SQL provider - The creation of the parameters is name-dependent and not order-dependent.

OleDb provider - The creation of the parameters is order-dependent and not order dependent.
 
 
 
 
PS: Please comment if this served your purpose by any chance. Happy coding :)

Using parentheses with object initializers

public class ClassWithDefaultConstructor
{
    public string Property { get; set; }
}
public class ClassWithConstructorWithParameters
{
    public ClassWithConstructorWithParameters(string property)
    {
        this.Property = property;
    }
    public string Property { get; set; }
}
   
Correct usages -
var c = new ClassWithDefaultConstructor { Property = "value" };
var c = new ClassWithDefaultConstructor() { Property = "value" };
var c = new ClassWithConstructorWithParameters() { Property = "value" };
 
Wrong usage -
var c = new ClassWithConstructorWithParameters { Property = "value" };
 
Reason -
If you are using a parameterless constructor, as shown, the parentheses are optional, but if you are executing a constructor that requires parameters, the parentheses are mandatory, o/w, the compiler would cry as below -
 
Compile error -
'LINQProcessing.ClassWithConstructorWithParameters' does not contain a constructor that takes 0 arguments

PS: Please comment if this served your purpose by any chance. Happy coding :)

Joins-to-C# Query Extension Methods Mapping

Joins and their corresponding LINQ Query Extension methods
Type of join
Query extension method
Example
Example Result
(By enumerating through the query variable and displaying the details on console)
Inner Join
Join
var makes = new string[] { "Audi", "BMW", "Ford", "Mazda", "VW" };
var cars = GetCars();
var query = makes.Join(cars,
make => make, car => car.Make,
(make, innerCar) => new { Make = make, Car = innerCar });
Make: Audi, Car:ABC456 Audi TT
Make: BMW, Car:DEF123 BMW Z-3
Make: Ford, Car:ABC123 Ford F-250
Make: Ford, Car:DEF456 Ford F-150
Make: VW, Car:HIJ123 VW Bug
Left Outer Join
GroupJoin
var makes = new string[] { "Audi", "BMW", "Ford", "Mazda", "VW" };
var cars = GetCars();
var query = makes.GroupJoin(cars,
make => make, car => car.Make,
(make, innerCars) => new { Make = make, Cars = innerCars });
Make: Audi
Car VIN:ABC456, Model:TT
Make: BMW
Car VIN:DEF123, Model:Z-3
Make: Ford
Car VIN:ABC123, Model:F-250
Car VIN:DEF456, Model:F-150
Make: Mazda
Make: VW
Car VIN:HIJ123, Model:Bug
Cross Join (Cartesian product)
SelectMany
var repairs = new List<Tuple<string, List<string>>>
{
Tuple.Create("ABC123",
new List<string>{"Rotate Tires","Change oil"}),
Tuple.Create("DEF123",
new List<string>{"Fix Flat","Wash Vehicle"}),
Tuple.Create("ABC456",
new List<string>{"Alignment","Vacuum", "Wax"}),
Tuple.Create("HIJ123",
new List<string>{"Spark plugs","Air filter"}),
Tuple.Create("DEF456",
new List<string>{"Wiper blades","PVC valve"}),
};
var query = repairs.SelectMany(t =>
t.Item2.Select(r => new { VIN = t.Item1, Repair = r }));
VIN:ABC123 Repair:Rotate Tires
VIN:ABC123 Repair:Change oil
VIN:DEF123 Repair:Fix Flat
VIN:DEF123 Repair:Wash Vehicle
VIN:ABC456 Repair:Alignment
VIN:ABC456 Repair:Vacuum
VIN:ABC456 Repair:Wax
VIN:HIJ123 Repair:Spark plugs
VIN:HIJ123 Repair:Air filter
VIN:DEF456 Repair:Wiper blades
VIN:DEF456 Repair:PVC valve

Extension method syntax - [source collection].[extension method].[extension method]…;

PS: Please comment if this served your purpose by any chance. Happy coding :)

Wednesday, February 15, 2012

Signing a .NET assembly with shared key file

Problem:
Generating a strong name key file (.snk) and signing an assembly with such file is common. What if you have to do it for multiple assemblies? For obvious reasons, it is not recommended to generate a separate .snk file for each of your assemblies. There comes the age-old principle of "re-use".
One simple solution this is to use the <Browse...> item in the 'Signing' tab on project properties window and point to the common key file. What's wrong with this approach?
Well...nothing is indeed wrong with it. However, you will observe that this approach creates a copy of the key file in each of your individual project folders. In usual cases, this is not desired. So, the problem now cuts down  to the point of determining how to use the same key(as in previous approach), still having it at a single location. Let me put the problem statement in the easiest form - How to share a key file between multiple assemblies?
(Unless you are a beginner or haven't come across such requirement as yet, this should be a known pick.)

Solution:
  1. Generate a strong name file using the sn utility.
    sn –k SomeKey.snk(Refer the msdn documentation for more details on this step)
  2. Place the SomeKey.snk in a location accessible to all your assemblies.
  3. Add the key file to each of your project folders as an existing item using the context menu
  4. While adding it, make sure you chose to add it as a link, which will not replicate the file. (Observe the arrow besides the Add button on the Add Existing Item dialog.)
  5. Go to project properties and on the Singing tab, select the key file from the dropdown.
While doing these, make sure your key file's properties window has Build Action set to None and Output Directory is set to Do Not Copy.




Please comment if this served your purpose by any chance. Happy coding :)

Thursday, February 9, 2012

.NET Memory Management

Picture-perfect!!! :)

[Click on the poster to see it with clarity]






Please comment if this served your purpose by any chance. Happy coding :)

Wednesday, February 8, 2012

WCF binding – Understanding and configuring buffer management

Problem:

Developing or consuming service-oriented applications? Ever came across HTTP 400’s? …a needless question though. It is not uncommon to find a WCF CommunicationException with HTTP 400 (Bad Request). Quite a few of these instances may happen to be returning an error message that would say – “The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element”.
In certain complex project architectures, you may not get to see the detailed error message, especially, if you are just working on the UI end of it.
To find out a solution for this, let us understand how WCF does the buffer management.


Background & Solution:
What?
In the simplest form, a buffer is a chunk of memory and buffer pool is a set of one or more buffers.
It all starts when the BufferManager is created. BufferManager creates and manages the buffers and buffer pools, depending on the values that you set in the binding configuration in the application’s config file. Let’s first see what those buffer-related values are.

MaxBufferPoolSize is the size of the largest buffer pool that the BufferManager can manage.
·         If, in case, allocating buffer to an incoming message would mean that it would exceed this limit, then, the message would take a new buffer out of the heap and the garbage collector takes care of it once used up.
·         If this value is 0(zero), it means that each request would take a new buffer out of the memory heap and will be taken care of, by the garbage collector.

MaxBufferSize is the size of the largest individual buffer that the buffer manager can allocate (to any buffer pool).
  • For streamed transfers, only the SOAP headers need to be buffered while the message body can be streamed on-demand. In such cases, this would just mean the maximum size of the SOAP headers. For buffered transfers, it is the maximum size of the headers and message body.
MaxReceivedMessageSize is the maximum size of a message that can be received on a channel.
For buffered transfers, this is the same as the MaxBufferSize.
  • For streamed transfers, this is either greater than or equal to MaxBufferSize (for obvious reasons mentioned above)

How?
When the BufferManager is created, a series of buffer pools are also created, with each pool holding up to a memory determined by MaxBufferPoolSize.
The buffers in each of these pools would have sizes in an incremental pattern of the multiples of 128, until it reaches the maximum allowed message size (as set by MaxBufferSize).
For example, if the MaxBufferSize is set to 450 bytes, the BufferManager would create 3 pools as –
1st pool that holds buffers of size 128 bytes each
2nd pool that holds buffers of size 256 bytes each
3rd pool that holds buffers of size 450 bytes (this pool should otherwise hold buffers of size 512, but since the MaxBufferSize is lesser than 512, it would limit it to 450)

Here is a logical depiction of the buffer pools from above example. The ‘n’ below represents the number of buffers each pool can hold.
So, for all practical purposes, n => MaxBufferPoolSize / buffer size that pool can hold.

Say, the MaxBufferPoolSize for the above example is 1800.



Note that each buffer pool’s maximum size is the same, though the sizes of the buffers being held by each of those differ.

When?
Buffers are not allocated when the pools are created. They are only allocated when a message arrives to be processed.

1.  Request arrives
2.  BufferManager tries to find a pool that can hold buffers that are sufficient for this message
3.  If appropriate pool is identified with available buffers, the message gets processed. Otherwise, the  
    message is allocated a buffer out of the heap (not managed by BufferManager).
4.  Also, If the message size is more than the MaxBufferSize, it is allocated an unmanaged buffer, on the 
    memory heap i.e., buffer that is garbage collected as when it is available for collection.
5.  Once processed, the buffer manager tries to put the buffer that held the message back into its pool for 
    reuse. However, if by doing so, the pool’s size exceeds the MaxBufferPoolSize, the buffer will not be 
    returned back to the pool.


Trade-off
If you need to process large messages, you can use a large MaxBufferSize. But, using too much memory would also decrement performance. As a developer, you should find a balance between time and memory.
As a thumb rule, if your server, normally has ‘n’ number of concurrent requests, then you may have to set the MaxBufferPoolSize as ‘n’ times the MaxBufferSize.


Example configuration
Finally, let us see a sample configuration setting w.r.t. the settings we defined in the "What?" section of this post.
<binding name="WSHttpBinding_SampleFeedService" closeTimeout="00:00:30" openTimeout="00:00:30"
receiveTimeout="00:00:30" sendTimeout="00:00:30" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="2097152" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
<security mode="None">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true" />
</security>
</binding>

Here is more detailed write-up on WCF Memory Buffer Management by Andrew.


Please comment if this served your purpose by any chance. Happy coding :)