View Ravichandran J.V.'s profile on LinkedIn RJV 's Blog: April 2009 Tweet @ravichandranjv

Translate

Wednesday, 22 April 2009

Returning a "var" type from a method

The "var" type is a new introduction in .Net 3.x and it is also well known as an implicitly typed variable. The syntactical constraints are that they can be declared

1. Only inside a method.
2. only in a local scope.
3. only inside the scope of a method call.
4. only in an initialized state before being used.

So, if you require a "var" type returned from a method, you can do as below:

public class MyVar{
public static object VarReturningMethod(){
var implicitVar=new{LastName="Jv",
FirstName="Ravichandran"};
object nestedGenericVar = implicitVar;
return nestedGenericVar;
}
static void Main(){
var getVar=VarReturningMethod();
System.Console.WriteLine(getVar);}
}

Anonymous Types

Anonymous types are the most convenient way of working with those types, which do not need extensive usage or heavyweight creational structures.

The below code assigns a "var" type with a new instance whose type is/are the value(s) and their corresponding identifiers.

var implicitVar = new { Name = "A", Price = 3 };

So, if you do a

Console.WriteLine(implicitVar.ToString());

the output will be:

{Name="A", Price=3};

!!

The additonal advantage is that the variable "implicitVar" now knows the identifier's "Name" and "Price" as properties. So, you can do a:

implicitVar.Name and implictVar.Price

!!!

Extension Methods

An ExtensionMethod is a great technique introduced in .Net 3.x that extends on the existing capability of a type.

The syntax required by an Extension Method is that it should be static and cannot be created inside a non-generic static class. The method should consist of a parameter of that type for which this method is an extension of.

Syntactically, it means that the parameter should be prefixed with the "this" keyword followed by the type and identifier. For example, if you want to create an extension method for a type called "MyClass" then an extension method can be created in another class as below:

public static class MyExtendingClass{
public static void MyExtensionMethodForMyClass(this MyClass obj){
// Some statements
}
}

The below example extends the System.Int32 class and provides for an extension method called "IsInString". So, when a call to Convert.ToInt32() works on a string, the resultant integer will be provided with the newly created extension method as well.

using System;
namespace ExtensionMethodsExample
{
public static class ExtensionsClass
{
public static bool IsInString(this object o)
{
if (o is Int32)
{
int i = (int)o;
Console.WriteLine("Parameter passed is an integer type" + i);
}
if (o.Equals("24"))
return true;
return false;
}
}

public static void Main(){
Console.WriteLine((Convert.ToInt32("22") + Convert.ToInt32("2")).IsInString().ToString());

}
}

StructureMap and Dependency Injection

StructureMap is a new library that provides for a container to manage the lifetime of an object. Because the container is responsible for instantiating an object, it has to know the types that exist in a class/interface.

The StructureMap library provides for an ObjectFactory and a Container class that helps in initialising (extracting an instance) types like interfaces and other non-instantiable types.


Object Factory
The below code, for example, initializes the container and tells it that the default concrete type (which should be returned by the container to the caller) for a request for MyInterface type is "HelloWorldClass".


ObjectFactory.Initialize(x =>{x.ForRequestedType ()
.TheDefaultIsConcreteType(); });



The Lambda Expression, "x =>", helps in providing for inline execution logic. The "ObjectFactory" container, in the above code snippet, is initialized with knowledge on "RequestedType" and "ConcreteType".


In the below code snippet, "var" type variable is used to initialize types and set the default type as in the previous code snippet. The second statement, below, injects the property with the SetProperty method and using the "target" lambda expression specifies the value for the property.


var container = new Container(r =>{
r.ForRequestedType().TheDefault.Is.OfConcreteType(); r.ForConcreteType().Configure.SetProperty(target => { target.Hello = "Hello World"; });
});


The complete code is at the end of this post. You will require StructureMap library that can be downloaded at: http://sourceforge.net/project/showfiles.php?group_id=104740


The StructureMap architecture is as below:





Source: Sourceforge.net

Dependency Injection(DI)

DI is a happening subject doing the rounds and it has entered the .Net domain, too, with a bang.

Use DI to isolate one class from the actual implementation of its dependencies.

"Depend upon Abstractions. Do not depend upon concretions"

DI happens when the creation of a type is told to it through either parameters passed to constructor (Constructor Injection) or property (Setter Injection).

The below code is based on both Constructor Injection and Setter Injection. I have used the TDD approach to write the example, which also includes a mock object (Rhino Mock). You will need NUnit, StructureMap, Rhino Mock, .Net 3.5 to execute the below code.

Commented lines are different scenarios, which you can uncomment and explore.


using NUnit.Framework;
using Rhino.Mocks;
using StructureMap;
namespace StructureMapSimple
{
public class Proxy
{
private MyInterface obj;
public Proxy(MyInterface ob)
{
obj = ob;
}
public Proxy() { }
public string CallHelloMethod()
{
return obj.SayHello();
}
}
public interface MyInterface
{
string SayHello();
}
public class HelloWorldClass : StructureMapSimple.MyInterface
{
private string strHello;
public HelloWorldClass(string helloString)
{
strHello = helloString;
}
string MyInterface.SayHello()
{
return strHello;
}
public string Hello
{
get { return strHello; }
set { strHello = value; }
}
}
class Program
{
static void Main(string[] args)
{
}
}
[TestFixture]
public class TestClass{
private Proxy ob1;
[SetUp]
public void init()
{
//ObjectFactory.Initialize(x =>
//{
// x.ForRequestedType ()

// .TheDefaultIsConcreteType();
//});
ob1 = new Proxy();
}
[Test]
public void TestSetterInjection()
{
var container = new Container(r =>
{
r.ForRequestedType().TheDefault.Is
.OfConcreteType();
r.ForConcreteType().Configure
.SetProperty(target => { target.Hello = "Hello World"; });
});
Assert.AreEqual(container.GetInstance().Hello, "Hello");
}
[Test]
public void TestConstructorInjection()
{
var container1 = new Container(r =>
{
r.ForRequestedType().TheDefault.Is
.OfConcreteType();
r.ForConcreteType().Configure
.WithCtorArg("helloString").EqualTo("Hello");
});
Assert.AreEqual(container1.GetInstance().Hello, "Hello");
}
[Test]
[Explicit]
// [ExpectedException("System.InvalidOperationException")]
public void ShouldSayHelloWithRhinoMocks()
{
MockRepository mocks = new MockRepository();
MyInterface store = (MyInterface)mocks.StrictMock(typeof MyInterface));

// is equal to "(MyInterface) StructureMap.ObjectFactory.GetInstance(typeof(MyInterface)); "
ob1 = new Proxy(store);
MyInterface ob2 = (MyInterface)StructureMap.ObjectFactory.GetInstance (typeof(MyInterface));
//Expect.Call(ob1.CallHelloMethod()).Return("Hello World");
Expect.Call(ob2.SayHello()).Return("Hello World");
mocks.ReplayAll();
string s = ob1.CallHelloMethod();
//StructureMap.ObjectFactory.Inject(typeof(MyInterface), store);
Assert.AreEqual("Hello World", s);
mocks.VerifyAll();
}
}
}