Category Archives: C#

An IoC Conundrum: Looking for feedback

Today at work, my boss and I were brainstorming on the best way to use IoC across all our code. During this, he proposed an idea for using IoC that at first made me feel uneasy with the way it was being used. But the more I think about it, the more I am amazed by its design. Let me set this up for you and the best way is with pictures.

Note: The code examples given here are not functional and just provided to give a rough idea of what is intended.

Explanation: 

  • The BaseLib is a library that contains all the interfaces we define. It also contains the CDepInjection class.
  • The CDepInjection class contains a static Register method that will find an assembly that corresponds to an interface and using Reflection, load it.
  • The Database library contains a CDatabase class with a static constructor that will be called from the previous step when the Database library is reflected and loaded. See image below.

Benefits:

  • By having all the interfaced in BaseLib, we are programming against an interface.
  • By having the CDepInjection class in BaseLib, there is only 1 place we need to update code and only 1 dll that we will need to deploy in production should changes be needed. (Note: We could have 100 servers running 100 application each and they may be windows services, web services, asp.net mvc apps, windows forms apps, console apps etc.).
  • By making a change in CDepInjection and telling it to map an interface name to the appropriate assembly and class and having the RegisterType be in the CDatabase class, we can create a new database class, CNoSqlDatabase in another assembly, deploy it, make a change to BaseLib by telling it to now map IDatabase to the CNoSqlDatabase and then deploy that to all our servers GAC. Now, everything will use the new CNoSQLDatabase.

Concerns I have:

  • Using a static constructor in CDatabase means that it will be called one per process and only when the assembly is loaded in the Register(..) method of CDepInjection. I’m not convinced that a static constructor would be the best thing to do. In essence, aren’t we just abstracting the mappings that would go in a config file and putting them into BaseLib instead of an app.config of BaseLib?
  • Resolving parent-child would necessitate having to call register in the ‘main’ method of all our applications. For instance, if CDatabase was going to need logging, it would have to call Register(“ILogging”) in the static constructor above the Container.RegisterType<IDatabase, CDatabase>() call.

I would very much appreciate a critique of this design. Thank you.

Advertisement
Tagged , , , , , , , ,

ASP.NET MVC Caching Dynamically generated JavaScript

One of the things you may occasionally have to do while using JavaScript is show dialogs and react to your users inputs. These could be in the form of alert boxes that are built into the language, growls, loading panels or even just a message added to an element. (Side note: The jQuery BlockUI plugin seems very promising).

The discerning user would realize that a website that targets a global audience has to be able to localize, globalize and internationalize to their language and a good starting place is to look at Scott Hanselman’s post on this very topic.

Globalization, Internationalization and Localization in ASP.NET MVC 3, JavaScript and jQuery – Part 1

One hacky way to get localized strings in JavaScript when they are in separate files is to have a localized file with all the localized text in it. Then based on the users language preference, load up the appropriate file and use the strings from there. But what if the strings come from a database and you need to generate this at runtime to be able to handle change without deployment again. Well here is how you can do it.

Read the article on JavaScriptView by elegantcode for more details. However, to summarize here are their steps:

  1. Create a controller method that return the view as a JavaScriptFileResult preferably in your home controller.
  2. Create a view that contains the localized strings in an array. I used a helper method to get the contents from the database dynamically. You may wish to add this to your home controllers view folder as well.
  3. Add a script block in the shared layout’s header to the URL for the JavaScript file.

All well and good. The file will now come down with the rest of the content as a JavaScript file and you can use the array of localized strings in your other JavaScript code.

BUT! The one problem you may notice is that the JavaScript source file is retrieved every time a request is made to the server. Thus you will need to cache it. To do so, we just need to add the OutputCacheAttribute onto the controller method that returns the JavaScript file.

[OutputCache(Location = System.Web.UI.OutputCacheLocation.ServerAndClient, Duration = 900, VaryByParam = "none")]

The only problem here is that the VaryByParam is set to none. That’s because we don’t have any parameters being passed into the method. This is a problem because two different requests can come in for varying locales and now the second one may get the cached value of the first one. Therefore, we need to pass in the locale as a parameter and then VaryByParam on that field. This will ensure that every locale has the file cached and changes made can go out without requiring a deployment of files to the server.

JsConstants

The script block in the _Layouts.cshtml file.

<script src="@Url.Content("~/Home/JsConstants?lcid=" + System.Threading.Thread.CurrentThread.CurrentCulture.LCID)" type="text/javascript"></script>

But of course, who wants to keep sending these Id’s over all the time for all our script files. So, the easiest way to do this would be to create an identifier that can be used to check language automatically. And then we can write, “lang” in the VaryByParam attribute option and remove the lcid parameter from JsConstants.

[OutputCache(Location = System.Web.UI.OutputCacheLocation.ServerAndClient, Duration = 900, VaryByParam = "lang")]

The code to make this work is as follows. [Sorry but I’m not quite sure where I found this gem from]

public override string GetVaryByCustomString(HttpContext context, string value)
{
	if (value.Equals("lang"))
	{
		return Thread.CurrentThread.CurrentUICulture.Name;
	}
	return base.GetVaryByCustomString(context,value);
}

fidllerJsConstants

As you can see from the image above, the first request for the JsConstants file containing the JavaScript returned 918bytes of data. Whereas, the subsequent call returned 0 bytes. The raw message returned reads as follows:

HTTP/1.1 304 Not Modified
Cache-Control: private, max-age=863
Expires: Sat, 03 Sep 2011 22:57:26 GMT
Last-Modified: Sat, 03 Sep 2011 22:42:26 GMT
Vary: *
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Sat, 03 Sep 2011 22:43:03 GMT

This indicates that we are able to cache the contents of the JavaScript file that was being generated dynamically and it will be refreshed after the Duration we set (900).

Happy Coding.

kick it on DotNetKicks.com

Generating Object Classes from XML

I ran into a need for generating classes that xml data can be deserialized into. I generally write this myself but today, I needed to do it faster.

Along came the Visual Studio XSD tool.

Open a VS command prompt.
Type ‘xsd file.xml’. This will generate a file.xsd.
Then type, ‘xsd file.xsd /classes’. This will generate a file.cs file that you can then use to deserialize into.

For more details, check out this cool link http://sharpertutorials.com/using-xsd-tool-to-generate-classes-from-xml/

Poor Man’s Validation

Does your validation drive you crazy? Are you writing too much validator code? Have you lost your sense of humor?

image

Well, not to worry because now, there’s a little hack to make Validation easier.

Lets say I had a Company class as defined by:

    public class Company
    {
        public string Title
        {
            get;
            set;
        }
    }

Now, say I wanted to add validation to this so that the

  • Title is Required
  • Title must be up to 10 characters
  • Title can only be Alpha and space

In order to achieve this quickly, you can add the System.ComponentModel.DataAnnotations.dll file to your project (Make sure its the latest one from Codeplex). Then update your class definition as follows:

    public class Company
    {
        [Required]
        [StringLength(10)]
        [RegularExpression("[A-Za-z\\s]+")]
        public string Title
        {
            get;
            set;
        }
    }

Now you can run the following code to validate your class instance as follows:

    //
    // Test instantiation
    ValidationContext vc = null;
    bool bCanCreate = false;
    List<ValidationResult> validationResults = new List<ValidationResult>();
    Company _company = new Company();

    //
    // Test 1 : Acceptable test undeo 10 characters and alpha.
    _company.Title = "The Title";
    vc = new ValidationContext(_company, null, null);
    bCanCreate = Validator.TryValidateObject(_company, vc, validationResults, true);
    Debug.Assert(bCanCreate == true);

    //
    // Test 2: Failure test 
    _company.Title = "32 Pan";
    vc = new ValidationContext(_company, null, null);
    bCanCreate = Validator.TryValidateObject(_company, vc, validationResults, true);
    Debug.Assert(bCanCreate == false);

    //
    // Test 3: Failure test 
    _company.Title = "";
    vc = new ValidationContext(_company, null, null);
    bCanCreate = Validator.TryValidateObject(_company, vc, validationResults, true);
    Debug.Assert(bCanCreate == false);

    //
    // Test 4: Failure test 
    _company.Title = "abcdefghijklm nopqrstuvwxyz";
    vc = new ValidationContext(_company, null, null);
    bCanCreate = Validator.TryValidateObject(_company, vc, validationResults, true);
    Debug.Assert(bCanCreate == false);

So now you’re bound to be validator approved.

image

Tagged , , , , ,

Excelcification: Brain Teaser Code

Problem: Someone at work recently asked me how you would go about converting excel header rows into integers. In the image below, you see each column and its corresponding integer value.

 image

Thus, A = 0, B = 1, C = 2 and so on. Since I have no better word to describe this process, I’m going to call it Excelcification.

Def: Excelcification. The act of converting a alpha column into its numeric representation.

However, Excel cells go from A to Z and then become AA, AB, AC etc. So if Z = 25, AA = 26, AB = 27 and so on.

Your mission is to create a method that takes a string that corresponds to the excel column (don’t have to worry about spaces etc for now) and change that to its integer value.

 

In case you didn’t know, the largest column in Excel 2010 that I could see was XFD.

image

So what is the Excelcification of “XFD”?

 

[Jeopardy theme music plays…]

 

[Some time later…]

 

[Some more time later…]

 

Are you done? How did you do it?

 

My process was to recognize that this is going to be Base 26 arithmetic, also know as Hexavigesimal. But you didn’t need to know that. If you know how base 2 (binary) works, you can extrapolate it to work for base 26.  So how does base 2 work. If you remember your truth tables from high school/college, you would know that in binary:

01 = 2^0

10 = 2^1

11 = 2^1 + 2^0

 

Now extrapolate this for base 26 and realize that in binary, your digits are only 0 and 1 whereas in hexavigesimal, your digits are 0 through 25. (See the link there to A through Z).

Thus,

A = (26^0) * Numeric_Value(A)

B = (26^0) * Numeric_Value(B)

etc.

 

So if you create a method for this your code should be:

         public static class ExtensionMethods
    {
        /// <summary>
        /// Converts a string into its hexavigesical (base 26) representation.
        /// </summary>
        /// <param name="sxCol">Input string of letters.</param>
        /// <returns>-1 if input is null or empty, base 26 integer representation of input otherwise.</returns>
        public static int Excelcify(this string sxCol)
        {
            int result = -1;
            sxCol = sxCol.ToUpper();

            if (string.IsNullOrEmpty(sxCol))
                return result;


            for (int i = sxCol.Length; i > 0; i--)
            {
                char _c = sxCol[i-1];
                //
                // Function =>  (26 ^ reversed_char_index) * char_value
                //          A = 1 ------ Z = 26 ------ AA = 27 ------ AZ = 54
                // 64 because there 'A' starts at index 65 and we want to give 'A' the value 1.
                result += Math.Pow(26, sxCol.Length - i).ToSafeInt() *  (_c.ToSafeInt() - 64);
            }

            return result;
        }
    } 

And you would call your code as such:

 int iResult = “A”.Excelcify();
Debug.Assert(res == 0);
iResult = "Z".Excelcify();
Debug.Assert(res == 25);
iResult = "AA".Excelcify();
Debug.Assert(res == 26);

 

Thus “AAA” = 702, and “XFD” = 16383.

That is exactly 2^14 cells for those binary folk!

Tagged , , , , ,