- Details
- Written by: Stanko Milosev
- Category: WPF
- Hits: 8200
These days I was learning autofac, and this article is sort of a product of my learning. This web page I was using for learning, and for writing this article.
Idea was to have two buttons, where one button will send a message to textbox, and another will display message.
In this article, I explained problem which I had, there you can also see my XAML, and in this article I explained hot to create ICommand, so these things I will not explain again.
First we need to add reference to Autofac in our project, I did it with NuGet:

Then we have to prepare our XAML and then we need to prepare our classes with dependency injection in mind.
So, here is how my classes look like:
public interface IOutput
{
void Write(string content, object obj);
}
public interface IDateWriter
{
void WriteDate(object obj);
}
public class TodayWriter : IDateWriter
{
private IOutput _output;
public TodayWriter(IOutput output)
{
this._output = output;
}
public void WriteDate(object obj)
{
this._output.Write(DateTime.Today.ToShortDateString(), obj);
}
}
public class TextBoxOutput : IOutput
{
public void Write(string content, object obj)
{
var ioCmessageDisplayTextBox = (TextBox)obj;
ioCmessageDisplayTextBox.Text = "Hello world! It is: " + content;
}
}
public class ShowMessageOutput : IOutput
{
public void Write(string content, object obj)
{
MessageBox.Show("Hello world! It is: " + content);
}
}
As you can see first I created IOutput interface which is like general interface for writing, after that I have created IDateWriter which is going to be "implementation" interface. TodayWriter is the class where all things come together, it is of type IDateWriter, and with constructor dependency injection on IOutput.
ShowMessageOutput and TextBoxOutput are implementations of IOutput interface.
Now, when we prepared our class, we have to prepare our WPF application.
In mainwindow.xaml.cs write following code:
public static IContainer Container { get; set; }
public MainWindow()
{
InitializeComponent();
var builder = new ContainerBuilder();
builder.RegisterType<TodayWriter>().As<IDateWriter>();
Container = builder.Build();
}
With that we are registering our class where "all things come together", we need that part as sort of a initialization, as much as I understood.
Next code we will use it on methods which are executed on click of button:
var builder = new ContainerBuilder(); builder.RegisterType<ShowMessageOutput>().As<IOutput>(); builder.Update(MainWindow.Container); WriteDate(obj);
With RegisterType we are deciding which interface implementation will be executed, and with Update we are updating autofac builder.
Also, interesting part of code to notice is:
public static void WriteDate(object obj)
{
using (var scope = MainWindow.Container.BeginLifetimeScope())
{
var writer = scope.Resolve<IDateWriter>();
writer.WriteDate(obj);
}
}
Example you can download from here, and here is github branch.
- Details
- Written by: Stanko Milosev
- Category: WPF
- Hits: 6653
While I was learning inversion of control from autofacs example, I got idea to write my application which I will use to "feel" IoC.
So, idea was to have two buttons where one will write a message to console, and second one will write same message to text box window. Idea looked simple, but... Problem was because I wanted to follow MVVM pattern, I have created command, binded click event, then all I had to do was to change textbox text, and that was actually a problem, I couldn't find a way simply to change the value...
Only way which I found was to send an object as parameter, something like:
CommandParameter="{Binding ElementName=IoCmessageDisplayTextBox}"
Where IoCmessageDisplayTextBox is text box on which I want to display my message.
So, here is my XAML:
<Window x:Class="IoCtest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:IoCtest"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext><local:ClickModel />
</Window.DataContext>
<Grid OverridesDefaultStyle="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
</Grid.RowDefinitions>
<TextBox x:Name="IoCmessageDisplayTextBox" Grid.Row="0" Grid.Column="0" TextWrapping="Wrap" Text="TextBox" AcceptsReturn="True" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible"/>
<Button Grid.Row="1" Content="Write to memo" Command="{Binding MyClick}" CommandParameter="{Binding ElementName=IoCmessageDisplayTextBox}" Height="30" VerticalAlignment="Bottom"></Button>
</Grid>
</Window>
Since I already explained how to create button click event using ICommand here, I will not do it again, I will just keep focus on method which will be executed when user clicks button.
Method looks like this:
public void ShowMessage(object obj)
{
TextBox IoCmessageDisplayTextBox = new TextBox();
IoCmessageDisplayTextBox = (TextBox)obj;
IoCmessageDisplayTextBox.Text = "Hello world!";
}
As you can see I had to convert object which I sent as parameter to TextBox, and then I was able to change text property of my TextBox.
Example you download from here, project is prepared for IoC learning, that is why it is more dirty then usual :) I hope that results of my learning I will post soon.
- Details
- Written by: Stanko Milosev
- Category: WPF
- Hits: 6407
One example of button and textbox stretching together to fill view:
<Window x:Class="IoCtest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:IoCtest"
Title="MainWindow" Height="350" Width="525">
<Grid OverridesDefaultStyle="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Grid.Column="0" TextWrapping="Wrap" Text="TextBox" AcceptsReturn="True" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible"/>
<Button Grid.Row="1" Content="Write to memo" Height="30" VerticalAlignment="Bottom"></Button>
</Grid>
</Window>
Important lines to notice are:
<Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="30"></RowDefinition> </Grid.RowDefinitions>
and attributes:
Grid.Row="0" Grid.Column="0"
and
Grid.Row="1" VerticalAlignment="Bottom"
- Details
- Written by: Stanko Milosev
- Category: WPF
- Hits: 7695
To write this article I was using this article.
To show examples of dependency injection, I will implement application which will on one button show some message and on the other button same that message it will save to file. Method for showing message will be called ShowMessage, method for saving mesage will be called WriteMessageToFile.
So, first I have created new WPF application and I called it DependencyInjectionExample. Then I prepared XAML, where I added page controls, with which I separated DI and non DI examples, so my XAML looks like this:
<Window x:Class="DependencyInjectionExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel>
<TabControl>
<TabItem Header="Without Dependency Injection">
<Grid Background="#FFE5E5E5">
<StackPanel>
<Button>
Show message
</Button>
<Button>
Write message to a file
</Button>
</StackPanel>
</Grid>
</TabItem>
<TabItem Header="Inversion of Control">
<Grid Background="#FFE5E5E5">
<StackPanel>
<Button>
Show message
</Button>
<Button>
Write message to a file
</Button>
</StackPanel>
</Grid>
</TabItem>
<TabItem Header="Dependency Injection - constructor">
<Grid Background="#FFE5E5E5">
<StackPanel>
<Button>
Show message
</Button>
<Button>
Write message to a file
</Button>
</StackPanel>
</Grid>
</TabItem>
</TabControl>
</StackPanel>
</Grid>
</Window>
My window now looks like this:

After that I prepared folders in which I will implement all my examples, so my solution looks like this: 
Second step is to create example without dependency injection. Since I am using MVVM approach, I will create ICommand functionality which I will attach it to XAML, as I already explained it here.
Idea is to have one class (in my case DoTheMessage), which will react on Notify method of same class - once to display message, once to save message to a file.
Class which reacts on button click looks like this:
public class WithoutDiViewModelShowMessage
{
private ICommand _buttonCommand;
DoTheMessageWithoutDi _doTheMessage = new DoTheMessageWithoutDi();
public ICommand ButtonClick
{
get { return _buttonCommand; }
set { _buttonCommand = value; }
}
public WithoutDiViewModelShowMessage()
{
ButtonClick = new RelayCommand(new Action<object>(_doTheMessage.ShowMesage));
}
}
public class WithoutDiViewModelWriteMesage
{
private ICommand _buttonCommand;
DoTheMessage _doTheMessage = new DoTheMessage();
public ICommand ButtonClick
{
get { return _buttonCommand; }
set { _buttonCommand = value; }
}
public WithoutDiViewModelWriteMesage()
{
ButtonClick = new RelayCommand(new Action<object>(_doTheMessage.WriteMessage));
}
}
Where part of XAML for writing / showing message without DI looks like this:
<TabItem Header="Without Dependency Injection">
<Grid Background="#FFE5E5E5">
<StackPanel>
<StackPanel.Resources>
<withoutDi:WithoutDiViewModelShowMessage x:Key="WithoutDiViewModelShowMessage" />
<withoutDi:WithoutDiViewModelWriteMesage x:Key="WithoutDiViewModelWriteMesage" />
</StackPanel.Resources>
<Button DataContext="{StaticResource WithoutDiViewModelShowMessage}" Command="{Binding ButtonClick}">
Show message
</Button>
<Button DataContext="{StaticResource WithoutDiViewModelWriteMesage}" Command="{Binding ButtonClick}">
Write message to a file
</Button>
</StackPanel>
</Grid>
</TabItem>
And class which actually show / write messages looks like this:
class ActOnMessage
{
public void ShowMessage(string message)
{
MessageBox.Show(message);
}
public void WriteMessageToFile(object obj)
{
string _exePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
string _file = _exePath + "\\helloWorld.txt";
try
{
TextWriter tw = new StreamWriter(_file);
// write a line of text to the file
tw.WriteLine("test");
// close the stream
tw.Close();
}
catch
{
MessageBox.Show("Unable to write file to: " + _file);
}
finally
{
MessageBox.Show("Mesage was successfully writen to: " + _file);
}
}
}
class DoTheMessageWithoutDi
{
private ActOnMessage _actOnMessage = null;
public void ShowMesage(object o)
{
if (_actOnMessage == null)
{
_actOnMessage = new ActOnMessage();
}
_actOnMessage.ShowMessage("Hello world!");
}
public void WriteMessage(object o)
{
if (_actOnMessage == null)
{
_actOnMessage = new ActOnMessage();
}
_actOnMessage.WriteMessageToFile("Hello world!");
}
}
As you can see I had to write to methods (WithoutDiViewModelShowMessage and WithoutDiViewModelWriteMesage), under the "DoTheMessageWithoutDi" class for writing and showing messages, which is not good since I would like to have one class and one method which will react on the message.
Now lets see solution with Inversion of Control (IoC). My IoC.cs looks like this:
public interface INofificationAction
{
void ActOnNotification(string message);
}
//showMessage implementation
class ShowMessage: INofificationAction
{
public void ActOnNotification(string message)
{
MessageBox.Show(message);
}
}
//writeMessageToFile implementation
class WriteMessageToFile : INofificationAction
{
public void ActOnNotification(string message)
{
string _exePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
string _file = _exePath + "\\helloWorld.txt";
try
{
TextWriter tw = new StreamWriter(_file);
// write a line of text to the file
tw.WriteLine("test");
// close the stream
tw.Close();
}
catch
{
MessageBox.Show("Unable to write file to: " + _file);
}
finally
{
MessageBox.Show("Mesage was successfully writen to: " + _file);
}
}
}
class DoTheMessageIoC
{
private INofificationAction _actOnMessage = null;
public void ShowMesage(object o)
{
if (_actOnMessage == null)
{
_actOnMessage = new ShowMessage();
}
_actOnMessage.ActOnNotification("Hello world!");
}
public void WriteMessage(object o)
{
if (_actOnMessage == null)
{
_actOnMessage = new WriteMessageToFile();
}
_actOnMessage.ActOnNotification("Hello world!");
}
}
First I implemented interface (INofificationAction), and then on the end, I assigned different methods to a interface.
Now let us see how it will look like with dependecy injection - constructor injection.
This is how my model now looks like:
//interface
public interface INofificationAction
{
void ActOnNotification(string message);
}
//showMessage implementation
class ShowMessage : INofificationAction
{
public void ActOnNotification(string message)
{
MessageBox.Show(message);
}
}
//writeMessageToFile implementation
class WriteMessageToFile : INofificationAction
{
public void ActOnNotification(string message)
{
string _exePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
string _file = _exePath + "\\helloWorld.txt";
try
{
TextWriter tw = new StreamWriter(_file);
// write a line of text to the file
tw.WriteLine("test");
// close the stream
tw.Close();
}
catch
{
MessageBox.Show("Unable to write file to: " + _file);
}
finally
{
MessageBox.Show("Mesage was successfully writen to: " + _file);
}
}
}
class DoTheMessageIoC
{
private INofificationAction _actOnMessage = null;
public DoTheMessageIoC(INofificationAction concreteImplementation)
{
this._actOnMessage = concreteImplementation;
}
public void Notify(object o)
{
_actOnMessage.ActOnNotification("Hello world!");
}
}
As you can see last class (DoTheMessageIoC) has constructor which expects INofificationAction as parameter. And ViewModel now looks like:
public class DiConstructorViewModelShowMessage
{
private static ShowMessage writer = new DependencyInjectionExample.DiConstructor.ShowMessage();
private ICommand _buttonCommand;
private DoTheMessageIoC _doTheMessage = new DoTheMessageIoC(writer);
public ICommand ButtonClick
{
get { return _buttonCommand; }
set { _buttonCommand = value; }
}
public DiConstructorViewModelShowMessage()
{
ButtonClick = new DiConstructorCommand(new Action<object>(_doTheMessage.Notify));
}
}
public class DiConstructorViewModelWriteMesage
{
private static WriteMessageToFile writer = new DependencyInjectionExample.DiConstructor.WriteMessageToFile();
private ICommand _buttonCommand;
private DoTheMessageIoC _doTheMessage = new DoTheMessageIoC(writer);
public ICommand ButtonClick
{
get { return _buttonCommand; }
set { _buttonCommand = value; }
}
public DiConstructorViewModelWriteMesage()
{
ButtonClick = new DiConstructorCommand(new Action<object>(_doTheMessage.Notify));
}
}
Here you can see for showMessage example:
private static ShowMessage writer = new DependencyInjectionExample.DiConstructor.ShowMessage();
private ICommand _buttonCommand;
private DoTheMessageIoC _doTheMessage = new DoTheMessageIoC(writer);
Example you can download from here (VS 2012).