We will have to define a custom event handler and a custom event args to return the injected dependency. The cLogTime class will raise this event when it needs to log something, but doesn't know which logger to use.
Start a new C# WPF project called LazyDependencyInjection.
We will be using MEF to locate our logger so add a reference to System.ComponentModel.Composition.
Let's work from the bottom up by adding a new class called ILogger. It will contain the interfaces and classes we need to do logging. One of the three logger classes defined here will be lazily injected.
using System;
using System.Diagnostics;
using System.Windows;
using System.ComponentModel.Composition;
namespace LazyDependencyInjection
{
public interface ILogger
{
void Print(String Msg);
}
public interface ILoggerData
{
eLogType Type { get; }
}
public enum eLogType
{
Window,
MsgBox,
Output
}
[Export(typeof(ILogger))]
[ExportMetadata("Type", eLogType.MsgBox)]
public class LogToMsgBox : ILogger
{
public void Print(string Msg)
{
MessageBox.Show(Msg);
}
}
[Export(typeof(ILogger))]
[ExportMetadata("Type", eLogType.Output)]
public class LogToOutput : ILogger
{
public void Print(string Msg)
{
Debug.WriteLine(Msg);
}
}
[Export(typeof(ILogger))]
[ExportMetadata("Type", eLogType.Window)]
public class LogToWindow : ILogger
{
public void Print(string Msg)
{
Application.Current.MainWindow.Content
= Msg;
}
}
}
using System;
namespace LazyDependencyInjection
{
public class WhichLoggerEventArgs : EventArgs
{
public ILogger Logger;
}
public delegate void WhichLoggerEventHandler(object sender, WhichLoggerEventArgs e);
class cLogTime
{
public event
WhichLoggerEventHandler WhichLogger;
ILogger Logger = null;
public void
LogTime()
{
if (Logger == null)
{
WhichLoggerEventArgs e = new WhichLoggerEventArgs();
WhichLogger?.Invoke(this, e);
Logger = e.Logger;
}
Logger.Print(DateTime.Now.ToString());
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Windows;
namespace LazyDependencyInjection
{
public partial class MainWindow : Window
{
[ImportMany]
IEnumerable<Lazy<ILogger, ILoggerData>> Loggers;
public MainWindow()
{
InitializeComponent();
cLogTime TimeLogger = new cLogTime();
TimeLogger.WhichLogger +=
TimeLogger_WhichLogger;
TimeLogger.LogTime();
}
private void
TimeLogger_WhichLogger(object sender,
WhichLoggerEventArgs e)
{
CompositionContainer _container;
const eLogType LogType = eLogType.Window;
AggregateCatalog catalog = new AggregateCatalog();
catalog.Catalogs.Add(new
AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()));
_container = new CompositionContainer(catalog);
_container.ComposeParts(this);
e.Logger = Loggers.FirstOrDefault(l
=> (l.Metadata.Type == LogType)).Value;
}
}
}
Now, in MainWindow, replace eLogType.Window with eLogType.MsgBox and run it again. Are you impressed now? No? Oh, well.
No comments:
Post a Comment