Entlib 5 確實有能力做到這一點。我猜你的監聽器類中有一個[ConfigurationElementType(typeof(CustomTraceListenerData)],對吧?
Entlib 5被設計成獨立於容器,因此我們不能依賴任何類型的自動因爲每個容器都有不同的表現,所以你需要告訴Entlib調用哪個構造函數,以及應該注入哪些依賴關係,這是通過你的配置數據類來完成的。
我打了一個快速示例。這裏的跟蹤偵聽器 - 沒有太多特殊:
[ConfigurationElementType(typeof(GuiTraceListenerData))]
public class GuiTraceListener : TraceListener
{
private readonly ILogFormatter formatter;
private readonly IGuiController guiController;
public GuiTraceListener()
: this(string.Empty, null, null)
{
}
public GuiTraceListener(string name)
: this(name, null, null)
{
}
public GuiTraceListener(string name, ILogFormatter formatter, IGuiController guiController) : base(name)
{
this.formatter = formatter;
this.guiController = guiController;
}
public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id,
object data)
{
if ((Filter == null) || Filter.ShouldTrace(eventCache, source, eventType, id, null, null, data, null))
{
if (data is LogEntry)
{
if (formatter != null)
{
Write(formatter.Format(data as LogEntry));
}
else
{
base.TraceData(eventCache, source, eventType, id, data);
}
}
else
{
base.TraceData(eventCache, source, eventType, id, data);
}
}
}
public override void Write(string message)
{
guiController.Log(message);
}
public override void WriteLine(string message)
{
guiController.Log(message);
}
}
有趣的部分是在GuiTraceListenerData類:
public class GuiTraceListenerData : TraceListenerData
{
private const string formatterNameProperty = "formatter";
public GuiTraceListenerData()
: this("unnamed", null, TraceOptions.None)
{
}
public GuiTraceListenerData(string name)
: this(name, null, TraceOptions.None)
{
}
public GuiTraceListenerData(string name, string formatterName)
: this(name, formatterName, TraceOptions.None)
{
}
protected GuiTraceListenerData(string name, string formatterName, TraceOptions traceOutputOptions)
: base(name, typeof (GuiTraceListener), traceOutputOptions, SourceLevels.All)
{
ListenerDataType = typeof (GuiTraceListenerData);
Formatter = formatterName;
}
[ConfigurationProperty(formatterNameProperty, IsRequired = false)]
[Reference(typeof(NameTypeConfigurationElementCollection<FormatterData, CustomFormatterData>), typeof(FormatterData))]
public string Formatter
{
get { return (string) base[formatterNameProperty]; }
set { base[formatterNameProperty] = value; }
}
protected override Expression<Func<TraceListener>> GetCreationExpression()
{
return() =>
new GuiTraceListener(Name,
Container.ResolvedIfNotNull<ILogFormatter>(Formatter),
Container.Resolved<IGuiController>());
}
}
特別是,看看那GetCreationExpression方法。這就是告訴entlib創建由這個config new代表的對象,調用該構造函數並解析格式化程序(如果指定了)和IGuiController。
然後,在我的測試程序(我用的WinForms只是要快)我初始化我的容器和應用程序是這樣的:
static void Main()
{
var container = new UnityContainer()
.AddNewExtension<EnterpriseLibraryCoreExtension>()
.RegisterType<IGuiController, MessageBoxGuiController>();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(container.Resolve<Form1>());
}
我Form1類需要一個寫進程作爲構造函數的參數。
有關Entlib 5如何構建的好處是,您可以在執行此操作時獲得幾乎自動的配置工具支持 - 無需編寫單獨的配置節點。您的運行時配置元素是您所需要的 - 只需使用配置工具將該DLL複製到相同的目錄中,它就會將其提取出來。
無論如何,從這裏開始,它只是工作。
希望這會有所幫助。如果你想要更多的細節,請給我一個線路,我可以發送給你整個工作項目。
-Chris
請問您可以展示可用於GUITraceListener的構造函數,以及如何解決類型GUITraceListener。 – 2010-08-09 08:28:27
我沒有自己解決GUITraceListener,這是由企業庫本身通過app.config中的配置條目完成的。 但是,我將添加我爲GUITraceListener添加到我的職位的構造函數。等一下。 :-) – 2010-08-09 08:29:29