DCSIMG
July 2008 - Posts - Rotem Bloom's Blog

Rotem Bloom's Blog

Share knowledge on .NET and web development

News

About Me

Glad to help and share knowledge on .NET and also huge fan of Dream Theater.

Contact me via messenger

View Rotem Bloom's profile on LinkedIn

Dream Theater Pics

Blogs I Read

July 2008 - Posts

WCF Best Practices: How to Dispose WCF clients

Use of the using statement (Using in Visual Basic) is not recommended for Dispose WCF clients. This is because the end of the using statement can cause exceptions that can mask other exceptions you may need to know about.

using (CalculatorClient client = new CalculatorClient())
{
...
} // <-- this line might throw
Console.WriteLine("Hope this code wasn't important, because it might not happen.");

The correct way to do it is:
try
{
...
client.Close();
}
catch (CommunicationException e)
{
...
client.Abort();
}
catch (TimeoutException e)
{
...
client.Abort();
}
catch (Exception e)
{
...
client.Abort();
throw;
}

Tune your .NET Application that suffer from contention, poor performance, and deadlocks

Hi,

If you develop .NET application that uses:

  • CLR thread pool
  • You have available CPU cycles
  • Your application performs I/O bound operations such as calling a Web method or accessing the file system
  • The ASP.NET Applications/Requests In Application Queue performance counter indicates that you have queued requests

If you are unsure whether your application is using the CLR threat pool you can check as follows. Your application may be using the CLR thread pool if any of these conditions is true:

  • Your application makes Web service calls.
  • Your application uses the WebRequest or HttpWebRequest classes to make outgoing Web requests.
  • Your application explicitly queues work to the thread pool by calling the QueueUserWorkItem method

You can tune .NET thread pool using maxWorkerThreads, minWorkerThreads, maxIoThreads, minFreeThreads, minLocalRequestFreeThreads and maxconnection attributes in App.config or Web.config file.

ConnectionManagment section:

The maxconnection attribute in App.config\Web.config limits the number of concurrent
outbound calls. This setting does not apply to local requests (requests that originate from ASP.NET
applications on the same server as the Web service). The setting applies to outbound connections
from the current computer, for example, to ASP.NET applications and Web services calling other
remote Web services.

The default setting for maxconnection is two per connection group. For desktop
applications that call Web services, two connections may be sufficient. For ASP.NET
applications that call Web services, two is generally not enough. Change the
maxconnection attribute from the default of 2 to (12 times the number of CPUs)
as a starting point.

Here is an example for the config settings:

<system.net>

  <connectionManagement>

      <add address="*" maxconnection="24" />

      <add address="[Specific IP]" maxconnection="10" />

  </connectionManagement>

</system.net>

 

The configuration is one way but lets say you install your application on different machines with different hardware parts like: Numbers of CPU, memory and so on. So better solution is to do it dynamically using code.

Here is a code example on ASP.NET application.

The function for updating the section will look like:

 

public const string CONNECTION_MANAGEMENT_ALL_IPS = "*";

public const int CONNECTION_MANAGEMENT_THREADS_PER_PROCESSOR = 12;

 

/// <summary>

/// Add -or- Update system.net --> connectionManagement section.

///    Best Performance for all IPs (12 Threads * CPU#).

/// </summary>

/// <param name="config">The Configuration to be updated.</param>

/// <returns>true if ConnectionManagement section was updated, otherwise return false.</returns>

public static bool ApplyConnectionManagement(Configuration config)

{

     return ApplyConnectionManagement(config,

          CONNECTION_MANAGEMENT_ALL_IPS,

          CONNECTION_MANAGEMENT_THREADS_PER_PROCESSOR * Environment.ProcessorCount);

}

 

/// <summary>

/// Add -or- Update system.net --> connectionManagement section.

/// </summary>

/// <param name="config">The Configuration to be updated.</param>

/// <param name="address">The Address to be added / updated.</param>

/// <param name="maxConnections">The Max Connections to update.</param>

/// <returns>true if ConnectionManagement section was updated, otherwise return false.</returns>

public static bool ApplyConnectionManagement(Configuration config, string address, int maxConnections)

{

    bool isUpdate = false;

 

    if (config == null)

        throw new ArgumentNullException("config");

 

    if (String.IsNullOrEmpty(address))

        throw new ArgumentNullException("address");

 

    if (maxConnections < 1)

        throw new ArgumentException("maxConnections must be greater than zero.", "maxConnections");

 

    NetSectionGroup netSectionGroup = NetSectionGroup.GetSectionGroup(config);

 

    ConnectionManagementSection connectionManagementSection = netSectionGroup.ConnectionManagement;

 

    if (connectionManagementSection.ConnectionManagement.Count == 0)

    {

        // Add configuration to all IPs (*)

        if (address == CONNECTION_MANAGEMENT_ALL_IPS)

        {

            connectionManagementSection.ConnectionManagement.Clear();

 

            // Add new required element.

            ConnectionManagementElement connectionManagementElement =

                new ConnectionManagementElement(

                    address,

                    maxConnections);

 

            connectionManagementSection.ConnectionManagement.Add(connectionManagementElement);

            isUpdate = true;

        }

    }

    else

    {

        // Update Max Connection for required existing IP.

        foreach (ConnectionManagementElement connectionManagementElement in

            connectionManagementSection.ConnectionManagement)

        {

            if (connectionManagementElement.Address == address)

            {

                if (connectionManagementElement.MaxConnection != maxConnections)

                {

                    connectionManagementElement.MaxConnection = maxConnections;

                    isUpdate = true;

                }

                break;

            }

        }

    }

 

    return isUpdate;

 

}

 

Not on the Global.asax.cs file we will add the code that update the section:

protected void Application_Start(object sender, EventArgs e)

    // Load custom configuration file.

    Configuration configuration = ConfigurationManager.OpenMachineConfiguration();

    string configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Web.config");

            Configuration config = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap { MachineConfigFilename = configuration.FilePath, ExeConfigFilename = configPath }, ConfigurationUserLevel.None);

 

    if (ApplyConnectionManagement(config))

    {

       config.Save(ConfigurationSaveMode.Modified);

    }

}

 

On the first time you apllication start you will write the section using ConfigurationUtils.ApplyConnectionManagement(config) that return true. This will restart your application again but on the next apllication start the ConfigurationUtils.ApplyConnectionManagement(config) will return false.

 

Thread Pool (minFreeThreads, minLocalRequestFreeThreads):

Here is an example for the config settings:

<httpRuntime minFreeThreads="8" minLocalRequestFreeThreads="4" />

<processModel maxWorkerThreads="20" maxIoThreads="20" />

Now lets see it in code. first the function that update the thread pool:
 

/// <summary>

/// Apply Thread Pool Optimized Threading Settings.

///    Max = 100, Min = 50

/// </summary>

public static void ApplyThreadPoolOptimization()

{

    int maxWorkerThreads, maxCompletionPortThreads, minWorkerThreads, minCompletionPortThreads;

 

    ThreadPool.GetMinThreads(out minWorkerThreads, out minCompletionPortThreads);

    ThreadPool.GetMaxThreads(out maxWorkerThreads, out maxCompletionPortThreads);

 

    if (minWorkerThreads < 50) minWorkerThreads = 50;

    if (minCompletionPortThreads < 50) minCompletionPortThreads = 50;

    if (maxWorkerThreads < 100) minWorkerThreads = 100;

    if (maxCompletionPortThreads < 100) maxCompletionPortThreads = 100;

 

    ApplyThreadPoolSettings(maxWorkerThreads, maxCompletionPortThreads, minWorkerThreads, minCompletionPortThreads);

}

 

/// <summary>

/// Apply Thread Pool Threading Settings.

/// </summary>

/// <param name="maxWorkerThreads">The maximum number of worker threads in the thread pool.</param>

/// <param name="maxCompletionPortThreads">The maximum number of asynchronous I/O threads in the thread pool.</param>

/// <param name="minWorkerThreads">The new minimum number of idle worker threads to be maintained by the thread pool.</param>

/// <param name="minCompletionPortThreads">The new minimum number of idle asynchronous I/O threads to be maintained by the thread pool.</param>

public static void ApplyThreadPoolSettings(

    int maxWorkerThreads, int maxCompletionPortThreads,

    int minWorkerThreads, int minCompletionPortThreads)

{

    ThreadPool.SetMaxThreads(maxWorkerThreads, maxCompletionPortThreads);

    ThreadPool.SetMinThreads(minWorkerThreads, minCompletionPortThreads);

}

 

Again on your global.asax you can add call to update this setting:

protected void Application_Start(object sender, EventArgs e)

     ApplyThreadPoolOptimization();

}

 

 

The settings that are recommended may not work for all applications but If you are making one Web service call to a single IP address from each ASPX page, Microsoft recommends that you use the following configuration settings:

  • Set the values of the maxWorkerThreads parameter and the maxIoThreads parameter to 100.
  • Set the value of the maxconnection parameter to 12*N (where N is the number of CPUs that you have).
  • Set the values of the minFreeThreads parameter to 88*N and the minLocalRequestFreeThreads parameter to76*N.
  • Set the value of minWorkerThreads to 50. Remember, minWorkerThreads is not in the configuration file by default. You must add it.

More information and great microsoft article on this issue can be found on Microsoft Help & Support here.

 

 

 

Infrastructure decision: Which Log Framework you would prefer to work in your .NET application?

Hi All,

I want to hear your opinion on which log framework you would prefer? log4net, Enterprise Library log or maybe different log framework.

I already have an opinion but it would be great to see your comments on this issue.

Thanks,

Rotem

Customize your .NET object XML serialization with .NET XML attributes

Hi,

Serialize .net object to XML is very simple operation but let's say you want to control on the serialization and decide on the name of the XML attributes and elements that .net serialization create for your object. Well this is very simple to achive using built-in XML attributes (attributes like: XmlType, XmlAttribute, XmlArray, XmlArrayItem and more...) .NET gives us.

The code example include 3 classes: MainStory, Story and BaseStory. MainStory and Story both inherits from BaseStory, MainStory also contain list (List<Story>) of stories objects.

BaseStory:

[Serializable]

public class BaseStory

{

    protected const string DescriptionContentDelimiter = ":::";

 

    [XmlAttribute("content")]

    public string Content { get; set; }

 

    [XmlAttribute("description")]

    public string Description { get; set; }

}

 

MainStory:

 

[Serializable]

[XmlType("mainStory", Namespace = "www.mycompany.com", TypeName = "MainStory")]

public class MainStory : BaseStory

{

    private List<Story> stories = new List<Story>();

 

    public MainStory()

    {

    }

 

    public MainStory(string content)

    {

        string[] data = Regex.Split(content, DescriptionContentDelimiter);

        Content = data[0];

 

        if (data.Length > 1)

        {

            Description = data[1];

        }

    }

 

    [XmlArray("stories")]

    [XmlArrayItem("story")]

    public List<Story> Stories

    {

        get { return stories; }

        set { stories = value; }

    }

}

 

Story:

 

[Serializable]

[XmlType("story")]

public class Story : BaseStory

{

    public Story()

    {

    }

 

    public Story(string content)

    {

        string[] data = Regex.Split(content, DescriptionContentDelimiter);

        Content = data[0];

 

        if (data.Length > 1)

        {

            Description = data[1];

        }

    }

}

 

You can see that I use the built-in .NET XML attributes in order to achive my goal and control the way my XML serialization will look.

You can check the result using simple XmlHelper class that serialize your .NET object to XML file:

 

public static class XmlHelper

{

    /// <summary>

    /// Serialize object in XML format inside a file.

    /// </summary>

    /// <param name="filename">The file that serialize object will be saved.</param>

    /// <param name="objectToSerialize">The object to serialize.</param>

    public static void SerializeObject(string filename,

              object objectToSerialize)

    {

        using (Stream stream = File.Open(filename, FileMode.Create, FileAccess.ReadWrite))

        {

            XmlSerializer xs = new XmlSerializer(objectToSerialize.GetType());

            XmlTextWriter xmlTextWriter = new XmlTextWriter(stream, Encoding.UTF8);

            xs.Serialize(xmlTextWriter, objectToSerialize);

        }

    }

 

    /// <summary>

    /// Deserializes Object from a file.

    /// </summary>

    /// <typeparam name="T"></typeparam>

    /// <param name="filename">The file with the serialize object.</param>

    /// <returns></returns>

    public static T DeserializeObject<T>(string filename)

    {

        XmlSerializer xs = new XmlSerializer(typeof(T));

        T objectToSerialize;

 

        // Open for read only.

        using (Stream stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read))

        {

            objectToSerialize = (T)xs.Deserialize(stream);

        }

        return objectToSerialize;

    }

}

 

Parsing log files

Hi,

Have you ever got a task that required reading and parsing log files?

Well Log Parser 2.2 is the tool for you. Log parser is a powerful, tool that provides SQL query syntax to text-based data such as log files, XML files and CSV files. It also support Windows operating system files such as the Event Log, Registry, the file system and Active Directory.

You tell Log Parser what information you need and how you want it processed. The results of your query can be custom-formatted in text based output, or they can be persisted to more specialty targets like SQL, SYSLOG, or a chart.

There is also nice open source tool named: Visual Log Parser that helps you build and check you SQL log parser queries.

An overview on Log Parser cab found here. You can download Log Parser 2.2 from here.

I recommended this tool because it has great perfomance and also very easy to use.

Yours,

Rotem (Rock) Bloom

Nice wrapper for .NET ConfigurationManager

I wrote a nice and useful wrapper class for .NET ConfigurationManager class. What this class gives you:

  1. Internal cache for reading AppSettings values. The cache refresh itself when the file is change on the fly. (Just use Setting.Watch())
  2. You can read parameters from AppSettings section with generic support and also forward default value.
  3. You can read connection string and more...
Basically you can start working with the wrapper class instead of using .NET ConfigurationManager class. Of course you can change and add more functionality to the class that will suit your needs.

For example you can use the code:

bool isAllow = Setting.Get<bool>("MyAppSettingsKey");

Please add your comments, You can download the code from here.

How to Hoste Windows Live Messenger IM Control in you web site

Hi,

Adding messenger icon to your blog\web site and give your readers the ability to send you direct message to your messenger is very simple.

Go to: Windows Live Messenger Web Setting page and mark the checkbox "Allow anyone on the web to see my presence and send me messages".

After that go to Windows Live Messenger Create HTML and select your icon.

More information can be found on MSDN: Hosting the Windows Live Messenger IM Control

WCF Tips: Achieving High Performance. List of Key Design Decisions and Tuning Parameters

When working with WCF especially when middle-tier client applications uses Windows Communication Foundation, you sould always think about performance and take some major design decisions and tuning parameters.

  1. WCF client not generated as a proxy via SvcUtil.exe (Relevant more in .NET 3.0. In .NET 3.5 major performance improvement was made on WCF proxy creation).
    • Client shares service contract and schema (model classes as data contract).
    • Cache WCF proxy as a static member
      • One instance, once instance only, ever
      • Still thread-safe based on WCF under-the-covers network connection pool management
        Channels created directly via ChannelFactory
      • Hidden static channel exposed as a property
      • Getter/Setter logic does all initialization/abort/recreation as necessary
      • Maintains clean code in use of service operations
    • Expect up to 50% perfdegradation if you instance a generated proxy client class per Web Service call
      • Very different than ASMX
      • Same client caching approach in ASMX: no performance difference
  2. Static WCF Channel Logic code example:

private static object _channelLock= new object();

private static ChannelFactory<IMyService> _factory;

private static IMyService _channel;

 

public IMyService Channel

{

    get

    {

        IMyService localChannel = _channel;

 

        if (localChannel == null)

        {

            lock (_channelLock)

            {

                if (_factory == null)

                {

                    EndpointAddress remoteNodeEndPointAddress= new EndpointAddress("[someURI]");

                    _factory = new ChannelFactory<IMyService>("BasicHttpBindingMyServices", remoteNodeEndPointAddress);

                }

 

                if (_channel == null)

                {

                    _channel = _factory.CreateChannel();

                }

 

                return _channel;

            }

        }

 

        return localChannel;

    }

    set

    {

        lock (_channelLock)

        {

            if (((IChannel)_channel).State != CommunicationState.Opened)

            {

                ((IChannel)_channel).Abort();

                _channel = null;

            }

            if (_factory.State!= CommunicationState.Opened)

            {

                _factory.Abort();

                _factory = null;

            }

        }

    }

}

 

Service Operations Call (instanced per call):

 

public string SampleCall(string message)

{

    try

    {

        return this.Channel.SampleCall(message);

    }

    catch

    {

        this.Channel = null;

        throw;

    }

}

 

Now lets see some important Tuning Parameters:

  • Tcp binding is a custom binding, with binary encoding:

<customBinding>

  <binding name="CustomTcpBinding_PrimaryTradeServices">

    <binaryMessageEncoding maxReadPoolSize="64" maxWritePoolSize="32" maxSessionSize="4096">

      <readerQuotas maxDepth="64" maxStringContentLength="131072" maxArrayLength="16384"

              maxBytesPerRead="16384" maxNameTableCharCount="32768"/>

    </binaryMessageEncoding

    <tcpTransport manualAddressing="false" maxBufferPoolSize="524288" maxReceivedMessageSize="524288"

            connectionBufferSize="65536" hostNameComparisonMode="StrongWildcard"

            channelInitializationTimeout="00:00:05" maxBufferSize="524288"

            maxPendingConnections="100" maxOutputDelay="00:00:00.2000000"

            maxPendingAccepts="100" transferMode="Buffered" listenBacklog="400"

            portSharingEnabled="false" teredoEnabled="false">

    <connectionPoolSettings groupName="default" leaseTimeout="00:05:00" idleTimeout="00:02:00"

                            maxOutboundConnectionsPerEndpoint="100"/>

    </tcpTransport>

  </binding>

</customBinding>

  • .exe.config: For self-host service hosts (not for IIS-hosted services)

<runtime>

  <gcServerenabled="true">

  </gcServer>

</runtime>

  • For ASP.NET Worker Process (single worker process):All options off (worker process recycle off, rapid fail protection off)
  • For Service Implementation use: [ServiceBehavior(ConcurrencyMode= ConcurrencyMode.Multiple, InstanceContextMode= InstanceContextMode.PerCall)]
  • In .config file for Service –Uses custom WCF behavior to set throttles higher

<behavior name="TradeServiceBehaviors">

  <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true"/>

  <serviceMetadata httpGetEnabled="true" httpGetUrl=""/>

  <serviceThrottling maxConcurrentInstances="400" maxConcurrentCalls="400"/>

</behavior>

Well I hope these Design Decisions and Tuning Parameters will help you Building Interoperable, High-Performance Systems with Windows Communication Foundation (WCF).

 

I discover these great WCF tips when investigating MS "Service-Orientation Case Study" - The .NET StockTrader Application

Yours,

Rotem Bloom

Did you know that svcutil with /r does not work for MessageContract

I was trying to generate WCF proxy (Client) using svcutil.exe Visual Studio 2008 version. I also need to use the /r parameter of the svcutil.exe, so the generated proxy code will not generate definition for the objetcs from my reference assemblies.
The command I use is something like:
svcutil.exe /async http://localhost:8080/MyService /r:"C:\My.dll" /tcv:Version35 /out:MyClient.cs

In case the assembly My.dll contain .NET object that mark as [MessageContract] the generated proxy still contain definition for the MessageContract objects, so I have to change these objects to DataContract objects and then the generated proxy was created as expected.

You also need to remember that if your reference objects (on My.dll) contain objects form other assembly, You have to include this assemblies also in your svcutil command. So you new command will look like:
svcutil.exe /async http://localhost:8080/MyService /r:"C:\My.dll" /r:"C:\MyOtherObjects.dll" /tcv:Version35 /out:MyClient.cs

Useful commands extensions for Visual Studio 2008 IDE

Hi All,

PowerCommands for Visual Studio 2008 add some new useful commands for VS 2008 IDE.

Below is a list of the included in PowerCommands for Visual Studio 2008:

Enable/Disable PowerCommands in Options dialog
This feature allows you to select which commands to enable in the Visual Studio IDE. Point to the Tools menu, then click Options. Expand the PowerCommands options, then click Commands. Check the commands you would like to enable.
Note: All power commands are initially defaulted Enabled.

Format document on save / Remove and Sort Usings on save
The Format document on save option formats the tabs, spaces, and so on of the document being saved. It is equivalent to pointing to the Edit menu, clicking Advanced, and then clicking Format Document. The Remove and sort usings option removes unused using statements and sorts the remaining using statements in the document being saved.
Note: The Remove and sort usings option is only available for C# documents.
Note: Format document on save and Remove and sort usings both are initially defaulted OFF.

Clear All Panes
This command clears all output panes. It can be executed from the button on the toolbar of the Output window.

Copy Path
This command copies the full path of the currently selected item to the clipboard. It can be executed by right-clicking one of these nodes in the Solution Explorer:
The solution node; A project node; Any project item node; Any folder.

Email CodeSnippet
To email the lines of text you select in the code editor, right-click anywhere in the editor and then click Email CodeSnippet.

Insert Guid Attribute
This command adds a Guid attribute to a selected class. From the code editor, right-click anywhere within the class definition, then click Insert Guid Attribute.

Show All Files
This command shows the hidden files in all projects displayed in the Solution Explorer when the solution node is selected. It enhances the Show All Files button, which normally shows only the hidden files in the selected project node.

Undo Close
This command reopens a closed document , returning the cursor to its last position. To reopen the most recently closed document, point to the Edit menu, then click Undo Close. Alternately, you can use the CtrlShiftZ shortcut.
To reopen any other recently closed document, point to the View menu, click Other Windows, and then click Undo Close Window. The Undo Close window appears, typically next to the Output window. Double-click any document in the list to reopen it.

Collapse Projects
This command collapses a project or projects in the Solution Explorer starting from the root selected node. Collapsing a project can increase the readability of the solution. This command can be executed from three different places: solution, solution folders and project nodes respectively.

Copy Class
This command copies a selected class entire content to the clipboard, renaming the class. This command is normally followed by a Paste Class command, which renames the class to avoid a compilation error. It can be executed from a single project item or a project item with dependent sub items.

Paste Class
This command pastes a class entire content from the clipboard, renaming the class to avoid a compilation error. This command is normally preceded by a Copy Class command. It can be executed from a project or folder node.

Copy References
This command copies a reference or set of references to the clipboard. It can be executed from the references node, a single reference node or set of reference nodes.

Paste References
This command pastes a reference or set of references from the clipboard. It can be executed from different places depending on the type of project. For CSharp projects it can be executed from the references node. For Visual Basic and Website projects it can be executed from the project node.

Copy As Project Reference
This command copies a project as a project reference to the clipboard. It can be executed from a project node.

Edit Project File
This command opens the MSBuild project file for a selected project inside Visual Studio. It combines the existing Unload Project and Edit Project commands.

Open Containing Folder
This command opens a Windows Explorer window pointing to the physical path of a selected item. It can be executed from a project item node

Open Command Prompt
This command opens a Visual Studio command prompt pointing to the physical path of a selected item. It can be executed from four different places: solution, project, folder and project item nodes respectively.

Unload Projects
This command unloads all projects in a solution. This can be useful in MSBuild scenarios when multiple projects are being edited. This command can be executed from the solution node.

Reload Projects
This command reloads all unloaded projects in a solution. It can be executed from the solution node.

Remove and Sort Usings
This command removes and sort using statements for all classes given a project. It is useful, for example, in removing or organizing the using statements generated by a wizard. This command can be executed from a solution node or a single project node.

Extract Constant
This command creates a constant definition statement for a selected text. Extracting a constant effectively names a literal value, which can improve readability. This command can be executed from the code editor by right-clicking selected text.

Clear Recent File List
This command clears the Visual Studio recent file list. The Clear Recent File List command brings up a Clear File dialog which allows any or all recent files to be selected.

Clear Recent Project List
This command clears the Visual Studio recent project list. The Clear Recent Project List command brings up a Clear File dialog which allows any or all recent projects to be selected.

Transform Templates
This command executes a custom tool with associated text templates items. It can be executed from a DSL project node or a DSL folder node.

Close All
This command closes all documents. It can be executed from a document tab.

You can download PowerCommands 1.1 form: Here

 

How to load an assembly at runtime from specific location

Did you know that you do not have to put an assembly that an application must use at runtime in the bin folder of the application. You can put the assembly in any folder on the system, and then you can refer to the assembly at runtime.
 
In order to do so you can use the AssemblyResolve event. Here is the code example:
 

AppDomain currentDomain = AppDomain.CurrentDomain;

currentDomain.AssemblyResolve += new ResolveEventHandler(CustomResolveEventHandler);

 

private Assembly CustomResolveEventHandler(object sender, ResolveEventArgs args)

{

    //This handler is called only when the common language runtime tries to bind to the assembly and fails.

    //Retrieve the list of referenced assemblies in an array of AssemblyName.

    Assembly MyAssembly, objExecutingAssemblies;

    string strTempAssmbPath = "";

 

    objExecutingAssemblies = Assembly.GetExecutingAssembly();

    AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();

 

    //Loop through the array of referenced assembly names.

    foreach (AssemblyName strAssmbName in arrReferencedAssmbNames)

    {

         //Check for the assembly names that have raised the "AssemblyResolve" event.

         if (strAssmbName.FullName.Substring(0, strAssmbName.FullName.IndexOf(",")) == args.Name.Substring(0, args.Name.IndexOf(",")))

         {

             //Build the path of the assembly from where it has to be loaded.               

             strTempAssmbPath = "C:\\Myassemblies\\" + args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll";

             break;

          }

 

     }

     //Load the assembly from the specified path.                   

     MyAssembly = Assembly.LoadFrom(strTempAssmbPath);

     //Return the loaded assembly.

     return MyAssembly;

 }

CopySourceAsHtml setup for Visual Studio 2008

Hi All,

I created a setup for VS 2008 for the great Addins "CopySourceAsHtml".

Download

Enjoy :-)

WCF Practices: Writing single function for your entire WCF proxy calls

Let's say you want that all your WCF proxy calls will come from one function. This could be very useful and save a lot of code.
For example you can write your proxy exception handling in one place.

Here is the code example that work on .NET framework 3.5 only:

// The public function that execute the WCF proxy call

public void WCFProxyCall()

{

   CreateConferenceRequest r = new CreateConferenceRequest();

   Func createFunc = a => proxy.CreateConference(a);

 

   CreateConferenceResponse ci = ProxyWrapperOperation(createFunc, r);

}

 

 

// This is the single point function for the entire WCF proxy calls

// Here you can write code for all your WCF proxy calls.

private TResult ProxyWrapperOperation(Func operation, T parameter)

{

    TResult result;

    try

    {

        result = operation(parameter);

    }

    catch (TimeoutException timeProblem)

    {

         proxy.Abort();

         throw;

    }

    catch (FaultException unknownFault)

    {

         throw;

    }

    catch (CommunicationException commProblem)

    {

         proxy.Abort();

         throw;

    }

 

    return result;

}