The most common use of the ‘@’ is escape character for strings that contain backslashes in them [\]. So as things like code below is possible.

   1: string s = @"c:\windows\system32\";
   2: string s = @"this will retain my \r\n and not change to a line break";

 

But another usage is as an prefix for C# keywords.  In the code below you will notice that the keywords class static and bool are prefixed with the @ prefix.

   1: public class @class
   2: {
   3:     public static void @static(bool @bool)
   4:     {
   5:         if (@bool)
   6:             System.Console.WriteLine("true");
   7:         else
   8:             System.Console.WriteLine("false");
   9:     }
  10: }
  11: public class Class1
  12: {
  13:     [STAThread]
  14:     public static void Main()
  15:     {
  16:         cl\u0061ss.st\u0061tic(true);
  17:         @class.@static(false);
  18:         //class.static(true); //will not work 
  19:     }
  20: }

 

What this also enables is a scenario like the one below, which I do not like.

   1: public class @class
   2: {
   3:     public static void MyCoolMethod(bool @theBoolValue)
   4:     {
   5:         if (theBoolValue)
   6:             System.Console.WriteLine("true");
   7:         else
   8:             System.Console.WriteLine("false");
   9:     }
  10: }
  11: public class Class1
  12: {
  13:     [STAThread]
  14:     public static void Main()
  15:     {
  16:         cl\u0061ss.MyCoolMethod(true);
  17:         @class.MyCoolMethod(false);
  18:     }
  19: }

Spot the difference? In the method signature of MyCoolMethod the boolean parameter has the @ prefix however in the code below where the value of the boolean is being interrogated I have skipped using the identifier. This code will however work exactly the same. The reason for is simple

The identifiers are the same if ‘@’ prefix is removed when used, therefore @theBooleanValue and theBooleanValue are same

To quote

Two identifiers are considered the same if they are identical after the following transformations are applied, in order:

  • The prefix "@", if used, is removed.
  • Each unicode-escape-sequence is transformed into its corresponding Unicode character.
  • Any formatting-characters are removed

 

Most importantly the general advice on using the @ prefix on words that are not keywords  is NOT to use it. And having seen it in used in code have an instant distaste for it. I wonder if FxCop has a rule for checking the usage of the @ prefix for non keywords in identifiers?

 

Technorati Tags: ,,

Share/Save/Bookmark

, ,

Service Broker has a really good C# wrapper interface that comes part of the samples on Codeplex. If you need to work with service broker objects in the managed world then I would recommend using the interface from the .

Most samples I have seen demonstrate communicating within a single database, and hence use the SqlTransaction Class The code below is an example of sending a message to a SSB Service  in a SqlTransaction.

   1: private void SendMsgToSSB()
   2: {
   3:     SqlConnection conn = null;
   4:     SqlTransaction tran = null;
   5:     Conversation dialog = null;
   6:     Service client = null;
   7:     string connString = "Persist Security Info = False; Integrated Security = True; Initial Catalog = MyServiceBrokerDB; Data Source = .; Connect Timeout = 30;"
   8:     try
   9:     {
  10:         conn = new SqlConnection(connString);
  11:         conn.Open();
  12:  
  13:         // Begin a transaction
  14:         tran = conn.BeginTransaction();
  15:  
  16:         // Create a service object
  17:         client = new Service("MyCoolService", conn, tran);
  18:         client.FetchSize = 1;
  19:  
  20:         // Begin a dialog with the MyCoolService
  21:         dialog = client.BeginDialog(
  22:             "MyCoolServiceTarget", null, "DEFAULT",
  23:             TimeSpan.FromMinutes(1), false, conn, tran);
  24:  
  25:         // Create request message
  26:         string outgoingBody = "my really cool msg that broker understands";
  27:         Message request = new Message("DEFAULT",
  28:                                       new MemoryStream(Encoding.UTF8.GetBytes(outgoingBody)));
  29:  
  30:         // Send the message to the service
  31:         dialog.Send(request, conn, tran);
  32:  
  33:         dialog.End(conn, tran);
  34:         tran.Commit(); 
  35:     }
  36:     catch (ServiceException svcEx)
  37:     {//deal with this pesky service exceptions
  38:     }
  39:     finally
  40:     {//clean up here close connections etc.
  41:     }
  42: }

But in scenarios where the transaction needs to be elevated from a lightweight transaction to one that needs the aid of the DTC the SqlTransaction object is not going to cut it for you.

With a simple change (in bold and italicized) you can then support enlisting in a Distributed Transaction.

   1: public void SendMsgToSSB()
   2: {
   3:     SqlConnection conn = null;
   4:     Conversation dialog = null;
   5:     Service client = null;
   6:     string ConnectionString = "Persist Security Info = False; Integrated Security = True; Initial Catalog = MyServiceBrokerDB; Data Source = .; Connect Timeout = 30;";
   7:     try
   8:     {
   9:         conn = new SqlConnection(ConnectionString);
  10:         if (conn.State != ConnectionState.Open)
  11:         {
  12:             conn.Open();
  13:         }
  14:         conn.EnlistTransaction(Transaction.Current);
  15:  
  16:         // Create a service object
  17:         client = new Service("MyCoolService", conn, null);
  18:         client.FetchSize = 1;
  19:  
  20:         // Begin a dialog with the MyCoolService
  21:         dialog = client.BeginDialog(
  22:             "MyCoolServiceTarget", null, "DEFAULT",
  23:             TimeSpan.FromMinutes(1), false, conn, null);
  24:  
  25:         // Create request message
  26:         string outgoingBody = "my really cool msg that broker understands";
  27:         Message request = new Message("DEFAULT",
  28:                                       new MemoryStream(Encoding.UTF8.GetBytes(outgoingBody)));
  29:  
  30:         dialog.Send(request, conn, null);
  31:         dialog.End(conn, null);
  32:     }
  33:     catch (ServiceException ex)
  34:     { //deal with the exception
  35:     }
  36:     finally
  37:     { //clean up
  38:     }
  39: }

 

Again this code has a small issue what about if there is no Transaction available then sending a message without a transaction could be a bad thing. With one more change its ready to support both scenarios.

   1: public void SendMsgToSSB()
   2:   {   SqlTransaction tran = null;
   3:       SqlConnection conn = null;
   4:       Conversation dialog = null;
   5:       Service client = null;
   6:       string ConnectionString = "Persist Security Info = False; Integrated Security = True; Initial Catalog = MyServiceBrokerDB; Data Source = .; Connect Timeout = 30;";
   7:       try
   8:       {
   9:           conn = new SqlConnection(ConnectionString);
  10:           if (conn.State != ConnectionState.Open)
  11:           {
  12:               conn.Open();
  13:           }
  14:           if (Transaction.Current != null)
  15:           {
  16:               conn.EnlistTransaction(Transaction.Current);
  17:           }
  18:           else
  19:           {
  20:               tran = conn.BeginTransaction();
  21:           }
  22:  
  23:           // Create a service object
  24:           client = new Service("MyCoolService", conn, null);
  25:           client.FetchSize = 1;
  26:  
  27:           // Begin a dialog with the MyCoolService
  28:           dialog = client.BeginDialog(
  29:               "MyCoolServiceTarget", null, "DEFAULT",
  30:               TimeSpan.FromMinutes(1), false, conn, null);
  31:  
  32:           // Create request message
  33:           string outgoingBody = "my really cool msg that broker understands";
  34:           Message request = new Message("DEFAULT",
  35:                                         new MemoryStream(Encoding.UTF8.GetBytes(outgoingBody)));
  36:  
  37:           dialog.Send(request, conn, null);
  38:           dialog.End(conn, null);
  39:           if (tran != null)
  40:           {
  41:               tran.Commit();
  42:           }
  43:       }
  44:       catch (ServiceException ex)
  45:       { //deal with the exception
  46:       }
  47:       finally
  48:       { //clean up 
  49:       }
  50:   }

 

I have also been making a few changes to the interface that I intend to publish shortly.

Share/Save/Bookmark

, , , , ,

While working on a client project earlier this year we used a free suite of controls from called Krypton Toolkit. This toolkit served us really well to provide a consistent UX. One of my favorite features of this toolkit was the ButtonSpecs which could be added to almost every other control so that we could have text boxes with embedded buttons etc. How does this help you ask or why does it matter. Well if your like me, totally clueless on how to deal with resizing docking and anchoring, you will love ButtonSpecs

 

The other benefits of ButtonSpecs are for context menus, validation, lookups and other such things.

So if your doing windows forms development and are in need of a consistent UX for nix you cant go past the Component Factory’s offerings.

Additionally if your a MVP or own a blog with significant subscribers then you will be able to get the Phil Wright is giving away the entire Component Factory suite for free for you.

 

Technorati Tags: ,,,

Share/Save/Bookmark

, , ,