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