Injecting property dependencies

by Jacobus Meintjes January 24, 2010 20:48

First you will have to create the class with the properties that need to be injected.

   1:      public class Person
   2:      {
   3:          private int ival;
   4:         
   5:          //Dependency attribute is required for Unity to know that this is the property to
   6:          //inject with the registered object.
   7:          [Dependency]
   8:          public int IVal
   9:          {
  10:              get { return ival; }
  11:              set { ival = value; }
  12:          }
  13:   
  14:          public override string ToString()
  15:          {
  16:              return IVal.ToString();
  17:          }
  18:       }

Then create the Unity container that will be configured to inject the dependency.

   1:  IUnityContainer unityContainer = new UnityContainer();                        

You will now need to configure the UnityContainer to register the object required by the Person class.

   1:  //Person - class to assign the injected member to
   2:  //IVal - member name of class Person
   3:  //10 - Value to be assigned to IVal
   4:  unityContainer.Configure<InjectedMembers>()
   5:                      .ConfigureInjectionFor<Person>(new InjectionProperty("IVal", 10));

Doing this and using the Person class won't automatically assign the value to the member e.g.

   1:  Person p = new Person();
   2:   
   3:  //This will output 0 (zero) as IVal is unassigned, causing the default for int to be displayed.
   4:  Console.WriteLine("Value of IVal is {0}", p.ToString());

To allow for the property to be resolved, you will have to resolve the object using Unity's resolve method.

   1:  Person p = unityContainer.Resolve<Person>(); //Create Person and assign a value to IVal.
   2:   
   3:  //This will give a value of 10 as the property is assigned correctly.
   4:  Console.WriteLine("Value of IVal is {0}", p.ToString());

Getting property injections working correctly, took a while as I had to start using Factory classes to create and initialize classes required for my domain. Using factory classes allowed me to use Unity within my unit tests to register mocked objects.

Tags: , ,

C# | Dependency Injection | Unity

Configuring Unity for the Todo application

by Jacobus Meintjes December 18, 2009 10:33

 

Working on a small Todo MVC application, I had to start using Unity for dependency injection. As I worked with Unity, I learned how to configure it to let me inject into a constructor, property and method call.

 

Configuration starts off with the web.config, adding a new section to allow for Unity to be configured.

web.config

<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" requirePermission="false"/>

Registering the new section will allow you to set the path to the Unity configuration file.

<unity configSource="unity.config"/>

After doing this you can start with the configuration of Unity.

 

unity.config

 

<?xml version="1.0"?>

  <unity>

    <typeAliases>

      <typeAlias alias="string" type="System.String, mscorlib" />

      <typeAlias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity" />

     

      <typeAlias alias="ITodoRepository" type="Todo.Repository.Contracts.ITodoRepository, Todo.Repository.Contracts" />    

 

      <!-- To swop out dependancies, you swop the two Repositories below-->

      <typeAlias alias="TodoRepository" type="Todo.Repository.Sql.TodoRepository, Todo.Repository.Sql" />

      <!--<typeAlias alias="TodoRepository" type="Todo.Repository.Fake.TodoRepository, Todo.Repository.Fake" />-->

 

      <typeAlias alias="ITodoService" type="Todo.Services.Contracts.ITodoService, Todo.Services.Contracts" />

      <typeAlias alias="TodoService" type="Todo.Services.TodoService, Todo.Services" />

    </typeAliases>

 

    <containers>

      <container>

        <types>

          <type type="ITodoRepository" mapTo="TodoRepository" >

            <lifetime type="singleton" />

            <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration">

              <constructor>

                <param name="connectionString" parameterType="string">

                  <value value="data source=.\SQLExpress;integrated security=sspi; database=todo"/>

                </param>

              </constructor>

            </typeConfig>

          </type>

          <type type="ITodoService" mapTo="TodoService" >

            <lifetime type="singleton" />

            <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration">

            </typeConfig>

          </type>;

        </types>

      </container>

    </containers>

  </unity>

 

Important sections in the xml config file:

 

1.       Register the interface to use:

<typeAlias alias="ITodoService" type="Todo.Services.Contracts.ITodoService, Todo.Services.Contracts" />

 

2.       Register the class that implements the interface:

<typeAlias alias="TodoService" type="Todo.Services.TodoService, Todo.Services" />

 

3.       Mapping the interface to the implementation:

<type type="ITodoService" mapTo="TodoService" >

 

Example - Constructor injection

private ITodoService todoService;

public TodoController(ITodoService service)

{

     todoService = service;

}

Example - Property injection

[Dependency]

public ITodoService TodoService

{

     get;

     set;

}

 

This is accomplished using the Dependency attribute with the property.

 

Example – Method injection

private ITodoService todoService;

 

[InjectionMethod]

public void SetTodoController(ITodoService service)

{

     todoService = service;

}

 

This is accomplished using the InjectionMethod attribute with the method.

 

Note: The project that you want to use with Unity must compile into the web application’s bin folder.

 

Demonstrating DI

The best section to display the use of DI is the repository section in the config file:

1.       Register the interface to use: [Stays the same]

<typeAlias alias="ITodoRepository" type="Todo.Repository.Contracts.ITodoRepository, Todo.Repository.Contracts" />    

 

2.       Register the class that implements the interface:

<typeAlias alias="TodoRepository" type="Todo.Repository.Sql.TodoRepository, Todo.Repository.Sql" />

 

3.       Mapping the interface to the implementation:

<type type="ITodoRepository" mapTo="TodoRepository">

 

4.       Swopping the original implementation with a different one:

<typeAlias alias="TodoRepository" type="Todo.Repository.Fake.TodoRepository, Todo.Repository.Fake" />

 

The only difference to note, is when you implement a different type: type="Todo.Repository.Fake.TodoRepository, Todo.Repository.Fake" Only changing the namespace and the assembly allows you to use a completely different implementation of the interface. There will also be no need to recompile you're site.

Tags:

C# | Dependency Injection

T4 Code Generator - Create Resource Helpers

by Jacobus Meintjes December 07, 2009 22:35

With Visual Studio comes the T4 code generator, and I have been reading about it today. While reading online and trying it out, I created a resource helper template. What this template does is scan the current folder for all resource files and creates a static helper class to allow easy access to the resource variables without having to update code for the resource manually every time.

This is not a standard feature of Visual Studio, but you can download T4 Editor and T4 Toolbox to assist with templates and syntax highlighting.

Starting off, you will need to create a project and add the resource files. Then you need to add a text file, renaming it, to "ResourceGenerator.tt". The .tt extension lets the IDE know this is a custom generator file.

The first line of the file will consist of

   1:  <#@ template language="C#" HostSpecific="True" #>

HostSpecific="True" as explained on MSDN: "If you set the value of this parameter to true, you can access a property called Host in your text template." We will be using Host to retrieve the current project folder.

Then comes the normal C# using directives, with a slight difference.

   1:  <#@ import namespace="System.IO"#>
   2:  <#@ import namespace="System.Text"#>
   3:  <#@ import namespace="System.Text.RegularExpressions"#>

Next we start with the code

   1:  <#
   2:  string baseDir =  Host.ResolvePath("");
   3:  CreateResourceManagers(baseDir);
   4:  #>

<# and #> specifies code blocks

Then the bulk of the code to complete this demo.

   1:  <#+
   2:      public static void CreateResourceManagers(string dirPath)
   3:      {
   4:          DirectoryInfo directoryInfo = new DirectoryInfo(dirPath);
   5:   
   6:          foreach(FileInfo file in directoryInfo.GetFiles("*.designer.cs"))
   7:          {
   8:              string resource = string.Empty;
   9:              StringBuilder sb = new StringBuilder();
  10:              using(StreamReader reader = new StreamReader(file.FullName))
  11:              {
  12:                  resource = reader.ReadToEnd();    
  13:              }
  14:   
  15:              Regex pattern = new Regex(@"internal class (?<className>S*)");
  16:   
  17:              Match match = pattern.Match(resource);
  18:   
  19:              string className = match.Groups["className"].Value;
  20:              string fileName = className + "Helper.cs";
  21:   
  22:              sb.AppendLine("using System.Threading;");
  23:              sb.AppendLine("using System.Globalization;");
  24:              sb.AppendLine();
  25:              sb.AppendLine("namespace T4Demo.Resources");
  26:              sb.AppendLine("{");
  27:              sb.AppendLine("public static class " + className + "Helper");
  28:              sb.AppendLine("{");
  29:              sb.AppendLine("private static readonly CultureInfo ResourceCulture;");
  30:              sb.AppendLine();
  31:              sb.AppendLine("static " + className + "Helper()");
  32:              sb.AppendLine("{");
  33:              sb.AppendLine("ResourceCulture = Thread.CurrentThread.CurrentCulture;");
  34:              sb.AppendLine("}");
  35:   
  36:              pattern = new Regex(@"internal static string (?<property>S*).*[{]");
  37:   
  38:              match = pattern.Match(resource);
  39:   
  40:              if(match.Success)
  41:              {
  42:                  do
  43:                  {
  44:                      string property = match.Groups["property"].Value;
  45:                      sb.AppendLine();
  46:   
  47:                      sb.AppendLine("public static string " + property);
  48:                      sb.AppendLine("{");
  49:                      sb.AppendLine("get");
  50:                      sb.AppendLine("{");
  51:                      sb.AppendLine("" + className + ".Culture = ResourceCulture;");
  52:                      sb.AppendLine("return " + className + "." + property + ";");
  53:                      sb.AppendLine("}");
  54:                      sb.AppendLine("}");
  55:   
  56:   
  57:                      match = match.NextMatch();
  58:                  } while (match.Success);
  59:              }
  60:   
  61:              sb.AppendLine("}");
  62:              sb.AppendLine("}");
  63:   
  64:   
  65:              using(StreamWriter wr = new StreamWriter(dirPath + @"" + fileName))
  66:              {
  67:                  wr.Write(sb.ToString());
  68:              }
  69:          }
  70:      }
  71:  #>

The <#+ on line 1 says to the code generator that a C# block of code will follow. The code in this block is standard C#.

**Something that I found to help a lot. Code as far as you can in a C# class and then move it to the .tt file. Intellisense and syntax highlighting is a big help.

Reference used: http://www.olegsych.com

Click here to download the template

Tags:

C# | T4

string.Format with { some text }

by Jacobus Meintjes November 27, 2009 14:06

 

Trying to format a string containing a bracket {

1:
string id = "txtId";
   2:  StringBuilder sb = new StringBuilder();
   3:   
   4:  //Formatting this line, would give error: Input string was not in a correct format.
   5:  sb.AppendFormat("$("{0}").click(function () { ", id);
   6:   
   7:  sb.Append("$(this).slideUp();");
   8:  sb.Append("});");



The fix
   1:  string id = "txtId";            
   2:  StringBuilder sb = new StringBuilder();
   3:   
   4:  //Adding another bracket, will do the trick
   5:  sb.AppendFormat("$("{0}").click(function () {{ ", id);
   6:   
   7:  sb.Append("$(this).slideUp();");
   8:  sb.Append("});");

 

Tags:

C#

The 404 page in web.config

by edward.lategan October 19, 2009 11:30

What is a 404 page? According to Wikipedia the 404 page is a HTTP standard response code indicating that the client was able to communicate with the server but the server could not find what was requested. This could be a static page like "aboutme.aspx" or a dynamic content page like "default.aspx?page=phoenixcode".

In ASP.NET you have the option to create your own 404 page, and redirect the user to this page if the page does not exist, and not display an ugly error to the user.

If you would configured custom 404 page in web.config file in the "customErrors" section, this will tell the server to serve your 404 page, instead of showing an ugly message to the user.

   1:  <customErrors defaultRedirect="ErrorPage.aspx" mode="On">   
   2:      <error statusCode="404" redirect="404.aspx" />
   3:  </customErrors>


The code snippet above will send all users to a "ErrorPage.aspx" page if there is an error in the application, but if there is a 404 error, the user will be redirected to "404.aspx" instead.

You also don't need to parse the customErrors section to get name of the custom 404 page. Just throw HttpException:

   1:  throw new HttpException(404, "Article not found");
   
ASP.NET run-time will catch the exception and will redirect to the custom 404 page.

Tags: , , ,

C# | General

Powered by BlogEngine.NET 1.6.0.0
Theme by Mads Kristensen | Modified by Mooglegiant

About Me

Jacobus Meintjes
 
C# developer working with ASP.Net and/or Windows Forms.
Email Me

Cumulus

This will be shown to users with no Flash or Javascript.

Widget Twitter not found.

Root element is missing.X