How to pass arguments to constructor with Ninject dependency injector

by Naveen 28. April 2012 07:53

When using dependency injection, some time we need to pass additional parameters in constructor of that object. Ninject provides a very handy method that you can use to pass arguments when you bind the interfaces. I have a similar situation in my shopping web site. I uses MVC framework. It has an interface for repository component of the web site. One of the repository used in the application is Amazon web service. Each amazon web service needs to be associated with some identity parameters. The class that implements repository for amazon web service requires that caller passes identity parameters. You could argue that why this parameter is not a dependency as well so I could use binding for it. The problem is that it is hard to come up with a unified identity interface for each type of b2b web services. Therefore it made sense that each repository will handle this identity parameters on its own.

The following code shows how WithConstructorArgument method is used to pass parameters to constructor when Ninject creates instance of the object.

private void AddBindings()
{
   RequestIdentity identity = new RequestIdentity()
   {
      AssociateTag = ConfigurationManager.AppSettings["awsassociatetag"],
      AccessKey = ConfigurationManager.AppSettings["awsaccesskey"],
      SecretKey = ConfigurationManager.AppSettings["awssecretkey"]
   };
   NinjectKernel.Bind<IProductsRepository>().
    To<ProductsRepository>().
    WithConstructorArgument("identity", identity);
 }

Following code shows ProductRepository class implementation that is expecting the parameter to be passed to it.

public class ProductsRepository : IProductsRepository
{
     private RequestIdentity Identity { get; set; }
     public ProductsRepository(RequestIdentity identity)
     {
        if (null == identity)
        {
            throw new ArgumentNullException("identity");
        }
        Identity = identity;
     }
}
 

Views: 257

Tags: , ,

.Net | ASP.Net

How to use Ninject to insert dependency using constructor pattern

by Naveen 22. April 2012 15:01

Download Sample Application

Recently I was working on a prototype for implementation of logging mechanism for my application. Previously I used to use Unity for Dependency Injection (DI) to inject different logging frameworks into the application for integration and unit testing. Now I am switching to using Ninject for DI. In this post I will how you can to use Ninject in your applications. I will not go into details why I chose Ninject and not Unity for future projects. That will be topic for discussion for another day. For now I will summarize it in one line that Ninject is light weight and easy to use framework as compared to Unity.

Download Ninject Framework

You can download Ninject from Codeplex. Or better option is to get it using NuGet manager. Add reference to Ninject.dll in your project.

Create Interface and Classes for DI

For my logger, I created interface IAppLogger that will act as interface for all logging methods for my application. Following snippet shows sample of this interface.

public interface IAppLogger
{
  void Log(..............);
  void Log(..............);
}
    

Following code snippet shows sample of concrete class implementation for this interface. This class implements logging mechanism using Log4Net.

public class Log4NetLogger : IAppLogger
{
 private static readonly ILog MyLog = LogManager.GetLogger(typeof(Log4NetLogger));

 public Log4NetLogger()
 {
   BasicConfigurator.Configure();
 }
       
 public void Log(string id, string context, string methodName, 
                 string methodParams, string value)
 {
    MyLog.Info("Start");
    MyLog.Error(string.Format("{0} {1} {2} {3} {4}", 
        id, context, methodName, methodParams, value));
    MyLog.Info("End");
 }

 public void Log(string id, string context, string methodName, Exception ex)
 {
   MyLog.Info("Start");
   MyLog.Fatal(context, ex);
   MyLog.Info("End");
 }
}
    

Now that we have interface and class set up to include in DI, we can now look at how Ninject makes it easy to implement DI.

Implement Ninject Module

First step in using Ninject is to bind interface to object that will need to be created when application encounters DI. Create a class that derives from NinjectModule. Override Load method to include bindings. In this sample I will just use a simple implementation of Bind method. There are more advanced overloaded methods available to control the binding in more controlled way. For this sample, the following simple implementation will work.

public class LoggerModule : NinjectModule
{
  public override void Load()
  {
    Bind<IAppLogger>().To<Log4NetLogger>().InSingletonScope();
  }
}
    

What this code means is that every time there is an instance of IAppLogger to be injected into the application, create an instance of Log4NetLogger class. Since we need singleton instance for logger, we call InSingletonScope method that indicates to Ninject to create singleton Log4NetLogger class.

You can include all bindings of your application in one module. But it is preferred that you create multiple modules and include binding related to certain sections of the application into appropriate modules.

Add NinjectModules into framework

Now that we have implemented our NinjectModule we need a way to tell Ninject framework about this. You can add one more modules into IKernel object of Ninject. Following method show how DI framework gets to know about our modules.

static void SetupDI()
{
  NinjectKernel = new StandardKernel(new LoggerModule());
}
    

Add DI to class using Inject attribute

Now we have DI framework set up for our logger interface. Lets see how we are going to use DI in our classes. In this sample, I have create AmazonRepositary class. I would like to inject IAppLogger object into this class so I can log any errors or information into my logger. Following code snippet shows how I used Inject attribute to insert IAppLogger to class. In this case I am using Constructor Injection pattern.

public class AmazonRepository
{
   private IAppLogger _appLogger;
        
   [Inject]
   public AmazonRepository(IAppLogger appLogger)
   {
     _appLogger = appLogger;
   }

   public void GetProducts(SearchParameters searchParams, string ip)
   {
        .....
   }
}
    

Inject attribute lets Ninject framework know that when Ninject kernel is used to create an instance of AmazonRepository object, it will create an instance of IAppLogger object and inject that into class constructor. Following code shows how kernel object is used to create this class.

var repo = NinjectKernel.Get<AmazonRepository>();
    

You can see that your implementation does not need to know what logger class is going to be used when creating instance of injected interface. You have already set up the binding in NinjectModule. By writing few lines of code we have managed to use Ninject as our DI framework. In subsequent posts, I will discuss other DI patterns and some advanced use of binding mechanisms.

Sample Code

I have attached sample project with this post that I used for demonstrate use of constructor patterns for DI. This project was created using VS11 and .Net 4.5. There is nothing specific to .Net4.5 used in this implementation. You should just be able to use the same code in VS2010.

 

Views: 242

Tags: ,

.Net

Microsoft .Net Framework 4.5 Beta Failed - Incorrect Function

by Naveen 6. April 2012 06:41

While installing Visual Studio 11 on my development desktop, the installation failed with error saying Microsoft .Net Framework 4.5 Failed - Incorrect Function. Well that was not very information error message. But as a developer one thing is clear from this error message that installer is trying to call some function that does not exist or its signature does not match with what it was expecting. After doing some search, I found that it has something to do with conflict of .Net 4 and .Net 4.5 framework on same machine. All suggestions pointed to one thing to install .Net 4.5 framework independently. You will find the framework installer in following folder in your VS11 installation folder.

\packages\dotNetFramework\dotNetFx45_Full_x86_x64.exe

I tried to install .Net 4.5 framework separately. That did not work as well and installation failed. After digging around in my desktop, I found that I have QuickBooks installed which starts a background windows service when machine starts. That service has .Net framework assemblies loaded and will prevent update of .Net framework. So here are the steps that worked for me.

  • Start task manager
  • End all windows services related to QuickBooks. Easiest way to identify these services is that their names start with QB.
  • Install .Net 4.5 framework from folder mentioned above

The same steps will work if you have some other services that use .Net framework and may prevent upgrade.

 

Views: 485

Tags:

.Net

Programatically signing in to site using Basic Authentication using .Net

by Naveen 28. March 2012 08:43

This week I was evaluating a help desk application to use for our site. One of the key factors in decision making was ability to connect to application's API using some form of web service. It turns out that this application supported REST API. First thing I needed to look for was how do I authenticate request to extract data. This application uses BASIC authetication. That would not be my first preference to use any application that uses BASIC authentication because of concerns related to user credentials being exposed in clear text in request. In this post I will discuss how to submit a HTTP request with Basic Authentication.

Basic Authentication Protocol

Basic authentication protocol manadates that HTTP request should include Authorization header that contains user credentials in the following format.

        Authorization = Basic UserCredentials
        where
        UserCrdentials = Base64 encoded value of Login":"Password string
    

Now you can see why this mechanism is not safe because credentials are exposed in the header directly and it does not take any effort to decode this Base64 encoded pair. Thats the besides the point for this discussion.

Basic Authentication With .Net

Here is code snippet from my evaluation application. There is nothing fancy in this code. The code that relates to authentication has been highlighted.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Web;

namespace FreshdeskConsole
{
    class Program
    {
        const string BaseUrl = "https://{0}.freshdesk.com/";
        const string CompanyName = "byteblocks";
        const string LoginUrl = "login";
        const string TicketsUrl = "helpdesk/tickets.xml";
        const string LoginEmail = "xyz@byteblocks.com";
        const string Password = "mypassword";

        static void Main(string[] args)
        {
            GetAllTickets();
        }

        static void GetAllTickets()
        {
            var baseUrl = string.Format(BaseUrl, CompanyName);
            var ticketsUrl = string.Format("{0}{1}", baseUrl, TicketsUrl);

            var webReq = WebRequest.Create(ticketsUrl);
        
            var credentialsCache = new CredentialCache();
            credentialsCache.Add(new Uri(baseUrl), "Basic", GetUserCredentials());
            webReq.Credentials = credentialsCache;
            webReq.Headers.Add("Authorization", GetBasicAuthenticationData());
        
            webReq.Method = "GET";
            webReq.PreAuthenticate = true;
            webReq.ContentType = "application/x-www-form-urlencoded";

            var response = webReq.GetResponse();
            ProcessWebResponse(response);
        }

        static void ProcessWebResponse(WebResponse response)
        {
        }

        static NetworkCredential GetUserCredentials()
        {
            var credentials = new NetworkCredential(LoginEmail, Password);
            return credentials;
        }

        static string GetBasicAuthenticationData()
        {
            var authInfo = string.Format("{0}:{1}", LoginEmail, Password);
            var bytes = new UTF8Encoding().GetBytes(authInfo);
            var encodedInfo = Convert.ToBase64String(bytes);
            return string.Format("Basic {0}", encodedInfo);
        }
    }
}
    

NetworkCredentials and CredentialsCache

.Net framework exposes NetworkCredentials and CredentialsCache classes that you can use to set a user's credentials to attach to a web request. You can from the code above how this is done.

Authorization Header

This is something that I found out after spending couple of hours on trying to figure out why credentials were not being sent to web service. Although I had set CredentialsCache to WebRequest, the information was not being sent to server. So I had to go back to basics and do it old fashioned way of explicitly setting Authorization header.

If you have any questions about Basic authentication use in .Net, feel free to post a comment in this post and I will try to get back to you as soon as I can.

 

Views: 375

Tags: ,

.Net | ASP.Net

How to convert string collection to integer or custom types

by Naveen 15. February 2012 08:31

In this post I will discuss implementation of data conversion task that is performed very commonly in application. For example lot of time we put some data in configuration files. When we store data in configuration file, it is presented to us as a string or collection of strings. There are some simple methods available that can do simple casting of this string data to types like int, bool etc. But what do you do when the data needs more custom conversion. Some of the questions that I get from users are:

  • How to convert string collection to int list
  • How to convert array of string values to integers
  • How to convert collection of string values to custom type

Here is an example from one of my applications.

<add key="ItemIds" value="1,34,56,76,9" />
<add key="ItemColors" value="blue, yellow, red" />

These are two entries in configuration file. Fist one is list of IDs and second is list of colors. As you can see that list of IDs is going to be collection of integers and second one I need to convert to color codes.

There is Cast extension method available. If you try to use that, you will get null value back. For example following code does not work because what we have is a comma separated list of string values. So a cast to INT will fail.

var values = Config.Default.ItemId;
IEnumerable<int> itemIds = values.Cast<int>();

So how can we convert this comma separated list of values to collection of integer or custom types. There is a very handy extension method ConvertAll available on of all collection types that will allow you to perform this conversion. Lets look at signature of this method available on Array class.

public static TOutput[] ConvertAll<TInput, TOutput>(
    TInput[] array,
	Converter<TInput, TOutput> converter
)

This generic method allows us to specify type of input and output. And the heart of this method is Converter method. It allows you to specify the method that will be used to convert data from input type to output type. In some simple cases you can use the methods already available in the framework. And in cases where you need to do custom conversion, then you can implement your own method and provide that as converter.

Using Converter Implemented in .Net Framework

Here is an example that uses Convert.Int32 method as converter to convert array of string values into list of integers.

 var values = Config.Default.ItemId.Split(',');
 IEnumerable itemIds = Array.ConvertAll<.string, int>(values, Convert.ToInt32);

Using custom converter

Here is an example of custom converter method that takes string values of colors from my configuration file and then convert them into codes.

var colorValues = Config.Default.ItemColors.Split(',');
IEnumerable itemColors = Array.ConvertAll<string, int>(colorValues, ColorTextToCode);

public static int ColorTextToCode(string value)
{
  switch (value.Trim().ToUpper())
  {
    case "BLUE":
      return 1;
    case "RED":
      return 2;
    case "YELLOW":
      return 3;
    default:
      return 4;
  }
}

You can extend this to perform conversions to any custom type. This conversion is not limited to primitive types or simple types. You can use write converters to create objects of complex types.

 

Views: 743

Tags: ,

.Net

How to use transaction in Entity Framework

by Naveen 22. November 2011 05:51

In previous posts, how to insert new records using entity framework and how to update records using entity framework. Those two processes are foundation blocks of most of the data operations we all perform in an application. The examples that showed in those posts were very simple involving one record for one table. In more complex work flow processes you have more than one database operations that need to take place to accomplish the intended outcome. When you have multiple records and tables being manipulated, you have to ensure ACID nature of transactions. There are very few cases I have come across where one could afford to have change in one table succeed if another operation in the same chain fail.

In this post I will show how to use transactions in Entity Framework. If you have dealt with transactions in SQL server queries or for that matter any database operations, you will notice that when using Entity Framework the concept stays the same. You perform the following steps.

  • Create a transaction
  • Perform database operations with in scope of that transaction
  • Commit or rollback transaction depending on out come of database operation

When you are using Entity Framework, transactions are handled by Transaction framework. You will not find reference to those namespaces in EntityFramework assembly. Those references exist in System.Transactions assembly. Lets see how you will use transactions in entity framework.

Assembly reference and namespace

Add references to System.Transactions.dll assembly in your project. And now include System.Transactions namespace in your code file.

Create new transaction

Key to using transaction is creating a transaction or logically speaking create a transaction scope which will enclose all the data operations that need to be included in one single transaction. Use TransactionScope class to create new instance of implicit transaction scope for operations.

using System.Transactions;

var txScope = new TransactionScope();
using (txScope){ ......  }

Perform database operations

With in scope of transaction perform all the data operations that I talked about in previous posts.

try
{
 dataContext.Projects.Add(project);
 dataContext.SaveChanges();
}                        

Commit Transaction

After all the database operations have completed and succeeded, then you can commit transaction by calling Complete method on TransactionScope object.

try
{
 dataContext.Projects.Add(project);
 dataContext.SaveChanges();
 txScope.Complete();
}

If you are looking for method like Rollback, you will not find it. No, this does not mean that transaction can not be rolled back using Entity Framework. The framework is designed to commit a transaction only after Complete method is called. If you do not want to commit a transaction, you can explicitly call Dispose on TransactionScope object or wait till TransactionScope object goes out of scope.

Here is complete code snippet from one of my sample projects.

protected void OnAdd(object sender, EventArgs e)
{
  if (!ValidateContracts())
  {
    ErrorMessage_Label.Visible = true;
    return;
  }

  var project = new Project()
  {
   ProjectName = AntiXss.HtmlEncode(ProjectName_TextBox.Text.Trim()),
    ProjectDescription = AntiXss.HtmlEncode(ProjectDescription_TextBox.Text.Trim()),
    Active = true,
    Deleted = false,
    ClientId = _thisClient.ClientId,
    CreateDate = DateTime.UtcNow
  };

  var dataContext = new PMDataContext(Global.ConnectionString);
  using (dataContext)
  {
   var txScope = new TransactionScope();
   using (txScope)
   {
    try
    {
     dataContext.Projects.Add(project);
     dataContext.SaveChanges();
     txScope.Complete();
    }
    catch (UpdateException upEx)
    {
     //TODO: log this update exception
     System.Diagnostics.Debug.WriteLine(upEx.Message);
    }
    catch (Exception ex)
    {
     //TODO: log thjis general exception
     System.Diagnostics.Debug.WriteLine(ex.Message);
    }
   }
  }
}
 

Views: 985

Tags: , ,

.Net | ADO.Net | LINQ

How to update record using Entity Framework

by Naveen 18. November 2011 08:53

In previous post How to insert new record using Entity Framework, I discussed one aspect of CRUD operation in an application or process. In this post I will talk about another aspect of the process, how to update a record using Entity Framework. If you are building some kind of business intelligence aplication where only action you have to take is read the data, then you may not be interested in UPDATE part of the process. But most of the applications require you to undertake whole spectrum of operations. And UPDATE is big part of the process.

The process of updating database records using Entity Framework is pretty straight forward. In previous post you saw that you use the collection property of Data Context to add new object in it and then call SaveChanges method. You will still be using SaveChanges method. Only difference is that you are not operating on the collection object. First you will use LINQ query on Data Context to get instance of the record object. Then make the changes to that object and then call SaveChanges. Entity Framework keeps track of what records are being changed when you change any property value of an object. When you call SaveChanges, it prepares a list of objects that need to be updated. And then take appropriate action. All the tracking is transparent to you. The following code snippet shows how you can update record using Entity Framework.

protected void OnUpdate(object sender, EventArgs e)
 {
     if (!ValidateInput())
     {
         ErrorMessage_Label.Visible = true;
         return;
     }

     decimal billRate = 0.0M;
     if (!string.IsNullOrEmpty(BillRate_TextBox.Text.Trim()))
     {
         decimal.TryParse(BillRate_TextBox.Text.Trim(), out billRate);
     }
     var displayName = AntiXss.HtmlEncode(DisplayName_TextBox.Text.Trim());
     if (string.IsNullOrEmpty(displayName))
     {
         displayName = AntiXss.HtmlEncode(FirstName_TextBox.Text.Trim());
         if (!string.IsNullOrEmpty(AntiXss.HtmlEncode(LastName_TextBox.Text.Trim())))
         {
             displayName += string.Format(" {0}", AntiXss.HtmlEncode(LastName_TextBox.Text.Trim()));
         }
     }
     var dataContext = new PMDataContext(Global.ConnectionString);
     var member = (from memberData in dataContext.Members
                   where (memberData.CompanyId == _thisCompany.CompanyId 
                             && memberData.MemberId == _thisMember.MemberId)
                   select memberData).First();

     member.MemberFirstName = AntiXss.HtmlEncode(FirstName_TextBox.Text.Trim());
     member.MemberLastName = AntiXss.HtmlEncode(LastName_TextBox.Text.Trim());
     member.MemberDisplayName = displayName;
     member.Active = _thisMember.Active;
     member.Deleted = _thisMember.Deleted;
     member.BillingRate = billRate;
     member.Availability = Convert.ToInt32(Availability_Dropdown.SelectedValue);

     try
     {
         dataContext.SaveChanges();
     }
     catch (Exception ex)
     {
         // TODO: Log the exception.
         System.Diagnostics.Debug.WriteLine(ex.Message);
     }
}

The implementation gets record for a specified Member using LINQ query. Then updates various values. And at the end calls SaveChanges. Very simple and straightforward process.

 

Views: 953

Tags: , ,

.Net | ADO.Net | LINQ

How to map custom class name to database table with Entity Framework

by Naveen 17. November 2011 08:40

In earlier post, How to insert records in database using Entity Framework, I discussed how you can use code first approach to create a POCO (Plain old CLR object) and then use data context to manipulate the tables. In that example POCO name was one to one match with table names in the database. Entity Framework was able to map the table with class name without any problem.

But you will always have cases where table names will not match with class names. This will happen if you are trying to reuse some existing code where classes were created based on some older schema. But now you have database tables that have totally different names. Another example, which I will use in this discussion, is using ASP.Net membership provider tables and procedures. You will notice that each database table is prefixed with aspnet_ by default. Now if you have classes with named like aspnet_Applications in your project, it will violate all the coding standard constraints and policies. And if you have some TFS check-in policy in place then you are out of luck because all policies will be violated.

There is a simple solution to this problem. You can create your POCO names to comply with standard naming convention. For example in my application, I want to query aspnet_Applications table but I want to keep my class name as Application. Following code snipper shows how I defined my class.

using System.ComponentModel.DataAnnotations;

[Table("aspnet_Applications")]
public class Application
{
 public Guid ApplicationId { get; set; }
 public string ApplicationName { get; set; }
 public string Description { get; set; }
}

I added TableAttribute to the class and set the name of the actual database table to which this class maps to. To add this attribute you will need to include System.ComponentModel.DataAnnotations in your class file.

If you do not add this attribute, you will see an exception like below when trying to query data context for the objects from that table.

Invalid object name dbo.Application

You can follow the same approach to map data base fields to class properties that do not match one to one.

 

Views: 893

Tags: ,

.Net | ADO.Net | LINQ

How to read file already opened by another process

by Naveen 2. November 2011 18:33

Today I was creating a handy dandy console application to parse IIS log file to analyze visitor behavior on one of the client sites. I will not go into discussion on why I did not use some of available web site log tools. Bottom line is that what I needed to do for analysis was not available in any of the tools. Hence the reason for my home grown solution.

This post is not about what I was building. In this post I am going to discuss the first road block I ran into. When I tried to read IIS log file from server, I had the following exception thrown at me.

File Already Opened By Another Process

In my case it absolutely made sense because IIS is constantly writing to this file so it has handle open on it. The trick to solve this issue is that when you call File.Open you specify right set of flags for FileShare and FileAccess that match with what the parent process has set, then you can grab a handle on it. Something like this will do the trick.

var file = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);

Well, there is an easier approach if only thing you really want to do is read the file. You can simply copy the file to new location and then you will not be faced with already opened handle on the file. And once you are done, you can just delete the copy of the file. Here is code snippet from my little parser that I was trying to write.

using System;
using System.Text;
using System.IO;

namespace SiteLogParser
{
    class Program
    {
        static string LogFolder = "\\\\mywebserver\\WebSiteLogs\\mysite\\W3SVC8";
        static void Main(string[] args)
        {
            try
            {
                var logFiles = Directory.EnumerateFiles(LogFolder);
                Console.WriteLine("Log Files: {0}", logFiles.Count());
                foreach (var logFile in logFiles)
                {
                    var fileName = Path.GetFileName(logFile);
                    File.Copy(logFile, fileName);
                    var file = new FileStream(fileName, 
                      FileMode.Open, 
                      FileAccess.ReadWrite, 
                      FileShare.ReadWrite);
                    using (file)
                    {
                        var sr = new StreamReader(file);
                        var line = sr.ReadLine();
                        while (null != line)
                        {
                            Console.WriteLine(line);
                            line = sr.ReadLine();
                        }
                    }
                    File.Delete(fileName);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }
    }
}
 

Views: 677

Tags: ,

.Net | C#

Configure Memcached with Custom ASP.Net Configuration Section

by Naveen 4. October 2011 09:59

Download Sample Projects (222.32 kb)

In previous post Memcached in ASP.Net, I discussed at high level how you can use Memcached as a state server to store cache for application(s). If you look at the sample code for that post, you will notice that all the configuration for Memcached were hard coded including list of servers. But in real application you would want to have ability to configure Memcached from configuration file. In this post I will discuss writing a custom configuration section for your web.config file where you can provide all the settings for Memcached service.

Custom Configuration Section

To develop a custom configuration section for Memcached settings, you will need to create a class in a library assembly that derives from ConfigurationSection. Following code snippet shows that in my implementation I created a class MemcacheConfiguration.

public class MemcachedConfiguration : ConfigurationSection
{....}

Now we need to add properties for all the configuration settings that you would allow an admin to configure from the configuration file. Following code shows sample of few of the properties that I added to this class.

 [StringValidator(MinLength=1)]
 public string Servers
 {
    get
    {
       return this["servers"] as string;
    }
    set
    {
       this["servers"] = value;
    }
 }
 
 public bool Failover
 {
    get
    {
      return (bool)this["failover"];
    }
    set
    {
      this["failover"] = value;
    }
 }

Here is how the entry for this custom section looks like in web.config file.

<configuration>
  <configSections>
    <section name="MemcachedConfiguration" 
    type="ByteBlocks.MemcachedProvider.MemcachedConfiguration,ByteBlocks.MemcachedProvider" 
    allowDefinition="Everywhere"/>
  </configSections>
  
  <MemcachedConfiguration 
    servers="127.0.0.1:11211" 
    failover="true" 
    initConnections="2" 
    minConnections="2" 
    maxConnections="4" 
    socketTimeout="30">
   </MemcachedConfiguration>
</configuration>

You can get complete implementation of this custom configuration section from the attached sample. I will discuss all Memcached settings that are included in my custom configuration section that allows you to configure Memcached state server for optimal performance.

  • servers: This is list of comma separated server IP addresses along with the IP address on which Memcached service is configured to listen. Yes, you can have as many servers as you want in this list.
  • failover: This property is used to configure Memcached service to connect to alternate server if connection to current target fails. Set this property to false if you do not want to failover to other servers that you configured using servers setting. Leave it to true if you have a strong reason not to failover.
  • initConnections: This property is used to configure number of initial connections that memcached client should establish with service servers.
  • minConnections: This property is used to configure number of minimum connections to be maintained in the pool.
  • maxConnections: This property is used to set number of maximum connections to open in socket connection pool.
  • socketConnectionTimeout: This property is time in milliseconds for timeout for establishing connection with server that you have configured. This is just for establishing connection with server.
  • socketTimeout: This property is used to set timeout in milliseconds for connection to read data from the cache. This time is different from maxSocketConnectionTimeout.
  • maintenanceSleep: This property is used to set time in milliseconds for maintenance thread to run for socket pool clean up and clean up of dead objects etc. If you set this property value to 0 then clean up thread will not start and run.

Based on this custom configuration implementation, my cache provider code looks like as below.

private bool InitializeFromConfigurationFile()
{
   var config = ConfigurationManager.GetSection("MemcachedConfiguration") 
     as MemcachedConfiguration;
   if (null == config)
   {
      return false;
   }
   Servers = config.Servers.Split(",".ToCharArray());
   _pool.SetServers(Servers);
   _pool.InitConnections = config.InitConnections;
   _pool.MinConnections = config.MinConnections;
   _pool.MaxConnections = config.MaxConnections;

   _pool.SocketConnectTimeout = config.SocketConnectTimeout;
   _pool.SocketTimeout = config.SocketTimeout;
   _pool.MaintenanceSleep = config.MaintenanceSleep;
   _pool.Failover = config.Failover;

   _pool.Nagle = config.Nagle;
   return true;
}

You can download attached sample to see all this in action. If you have any question please drop me a line and I will try to get back to you as soon as I can.

 

Views: 1180

Tags: ,

.Net | ASP.Net

Smart Phones Poll

What smart phone do you currently own?





Show Results

Month List

Powered by BlogEngine.NET 2.0.0.49
Theme by Naveen Kohli