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.