Monday, April 4, 2011

Another IoC container-Ninject

In the previous articles(Unity(1), Unity(2),Unity(3),Unity(4)), I wrote some notes on Unity Container. Recently I used another IoC container -Ninject, which seems a bit lighterr and also easy to use. So I am going to write a bit notes on Ninject.

Here is the Site for Ninject. And .Codeplex has great reference on this as well.

Reference the assembly Ninject.Core.

using Ninject.Core;

We have an interface:

public interface IMyService
{
void Dowork();
}

We have a Service class:

public class MyService:IMyService
{
public void Dowork()
{
//...Write some code;
}
}

Now we create a CustomModule class inherited from StandardModule

public class CustomModule: StandardModule
{
public override void Load()
{
Bind< IMyService>().To< MyService>();
}
}

Notice this CustomModule class do the type mapping.

Once you create modules, you load them into a container called the kernel.

Now in the application entry (if it is console, in Main function, if this is a Asp.Net application we should reference the Ninject.Framework.Web assembly, add a global.asax file, and let the Global class inherited from NinjectHttpApplication)

Sample code:

class Program
{
static void Main(string[] args)
{
CustomModule module=new CustomModule();
IKernel kernel=new StandardKernel(module);
}
}

For Asp.Net application,

public class Global:NinjectHttpApplication
{
protected override IKernel CreateKernel()
{
CustomModule module=new CustomModule();
IKernel kernel=new StandardKernel(module);
return kernel;
}
}

When we want to resove the type from the container, it is also very simple:

For example, I have MyClass

public class MyClass
{
[Inject] //use the Inject attribute
public IMyService IMyService {get;set;}

protected void Method()
{
this.IMyService.Dowork();
//The method is called after resolving MyService from container
}
}

We will see use Ninject is simple, I will write some sample code on this later.

Some other points in Ninject is Contextual Binding, it is in the CustomModule class add conditions when do binding, it is also easy to understand, I am not going into details.

Wednesday, March 23, 2011

Create a Dragable object using Thumb

< Canvas>
< Thumb Name="myThumb" Canvas.Left="80" Canvas.Top="80" DragDelta="onDragDelta">
< /Canvas>


private void onDragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
Canvas.SetLeft(myThumb,Canvas.GetLeft(myThumb)
+e.HorizontalChange);
Canvas.SetTop(myThumb,Canvas.GetTop(myThumb)
+e.VerticalChange);
}

I have placed the Sample Code Here.

Monday, March 21, 2011

WPF Commands

Just write some note summary:

.Net framwork has several predefined Commands, they are static objects which are the following 5 static classes:
1. ApplicationCommands
2. EditingCommands
3. ComponentCommands
4. MediaCommands
5. NavigationCommands

Some of the predefined Commands don't need CommandBinding, for instance: ApplicationCommands.Cut, so we can write in xaml:

< Button Command="ApplicationCommands.Cut" CommandTarget="{Binding ElementName=myTextBox}" >

(Button, MenuItem Controls are Inherited from ICommandSource interface and let them to be able to associated with the Command property.

Some of the Predefined Commands Still need CommandBinding, for instance: ApplicationCommands.Help.


Like events, Commands also bubble up to the visual tree, for instance we have a visual tree

Window
|
|__Grid
|
|__Button

We can have the CommandBindings under the button node, we can also have the CommandBinding at Grid or Window node.

When do the CommandBinding, we specify the Command Excuted event handler to execute the code when Command is invoked. We can also specify the CanExecute event handler to enable or disable the command. Notice when a command is disabled, the UIElement associated with the command is disabled too.

We can create custom Command as well. WPF support Routed Command. (Notice SilverLight doesn't support this).

We just need to create a RoutedCommand static instance. Sometimes we may need to use singleton patten to create a Custom Command Class, for instance:

public class MyCommands
{
private static RoutedCommand launch;

static MyCommands()
{
launch=new RoutedCommand();
}

public RoutedCommand Lauch
{
get
{return lauch;}
}
}

SilverLight doesn't support RoutedCommand. But good thing is that SL4 support ICommand interface(Delegate/Relay Command).

For the ICommand interface, please read MSDN, it exposes 3 memembers:

Method:
CanExecute
Executed

EventHandler:
CanExecuteChanged

ICommand interface is more useful than RoutedCommands actually, especially in M-V-VM modle. We can set the Delegate Command as a property.

Here I just write some sample code use(I just placed the Delegate Command as a static class property in my sample)

Predefined Command (Doesn't need Command Binding, the eventhandler is predefined)

Predefined Command need Command Binding

Routed Command

Delegate Command(ICommand)

The sample code can be downloaded Here.

Build Actions (Resources vs Contents)

MediaPlayer or MediaElement can only be built as Contents.

For some of the pictures:

if we build the image as resources, the image will be include in the dll/exe for the application. (This may affect the efficiency) But for many small icons, it is better to build as resource.

if we build the image as contents, the image is not include in the dll.

INotifyPropertyChanged

In WPF we write the ViewModel class, we can get the class inherited from dependencyObject and register the class property as DependencyProperty. But Silverligth doesn't support this.

So the most common scenario is to let the class inherited from INotifyPropertyChanged interface, but when implement the interface, let's follow strictly with the sample code in MSDN.

for instance:

public class MyVMClass: INotifyPropertyChanged
{
private string length;

public event PropertyChangedEventHandler PropertyChanged;

private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}

public string Length
{
get {return this.length;}
set
{
if(value!=this.length)
{
this.length=value;
NotifyPropertyChanged("Length");
}
}
}

Notice the if statement is the property set block is important. that is only the value is different, the propertyChanged event is triggered.

Tuesday, March 15, 2011

C# 4.0 Features -- Tuple Type

It is very straightforward, I just write some sample code below:

using System;


namespace TupleExample
{
class Program
{
static void Main(string[] args)
{
Tuple< int, string, string[]> tuple1=
new Tuple< int, string, string[]>
(5,"test",new string[3]{"test1","test2","test3"});

//Console.WriteLine(tuple1.Item1.ToString());

var tuple2 = Tuple.Create("test", new Tuple< int,int,string>(3, 2, "test"));

//Console.WriteLine(tuple2.GetType());

var tuple3 = Tuple.Create(Tuple.Create("Test", 1), 3);

//Console.WriteLine(tuple3.Item1.Item2.ToString());
}
}
}

Friday, March 11, 2011